{"version":3,"file":"ShadowMapViewer.cjs","sources":["../../src/utils/ShadowMapViewer.js"],"sourcesContent":["import {\n DoubleSide,\n LinearFilter,\n Mesh,\n MeshBasicMaterial,\n OrthographicCamera,\n PlaneGeometry,\n Scene,\n ShaderMaterial,\n Texture,\n UniformsUtils,\n} from 'three'\nimport { UnpackDepthRGBAShader } from '../shaders/UnpackDepthRGBAShader'\n\n/**\n * This is a helper for visualising a given light's shadow map.\n * It works for shadow casting lights: DirectionalLight and SpotLight.\n * It renders out the shadow map and displays it on a HUD.\n *\n * Example usage:\n *\t1) Import ShadowMapViewer into your app.\n *\n *\t2) Create a shadow casting light and name it optionally:\n *\t\tlet light = new DirectionalLight( 0xffffff, 1 );\n *\t\tlight.castShadow = true;\n *\t\tlight.name = 'Sun';\n *\n *\t3) Create a shadow map viewer for that light and set its size and position optionally:\n *\t\tlet shadowMapViewer = new ShadowMapViewer( light );\n *\t\tshadowMapViewer.size.set( 128, 128 );\t//width, height default: 256, 256\n *\t\tshadowMapViewer.position.set( 10, 10 );\t//x, y in pixel\t default: 0, 0 (top left corner)\n *\n *\t4) Render the shadow map viewer in your render loop:\n *\t\tshadowMapViewer.render( renderer );\n *\n *\t5) Optionally: Update the shadow map viewer on window resize:\n *\t\tshadowMapViewer.updateForWindowResize();\n *\n *\t6) If you set the position or size members directly, you need to call shadowMapViewer.update();\n */\n\nclass ShadowMapViewer {\n constructor(light) {\n //- Internals\n const scope = this\n const doRenderLabel = light.name !== undefined && light.name !== ''\n let userAutoClearSetting\n\n //Holds the initial position and dimension of the HUD\n const frame = {\n x: 10,\n y: 10,\n width: 256,\n height: 256,\n }\n\n const camera = new OrthographicCamera(\n window.innerWidth / -2,\n window.innerWidth / 2,\n window.innerHeight / 2,\n window.innerHeight / -2,\n 1,\n 10,\n )\n camera.position.set(0, 0, 2)\n const scene = new Scene()\n\n //HUD for shadow map\n const shader = UnpackDepthRGBAShader\n\n const uniforms = UniformsUtils.clone(shader.uniforms)\n const material = new ShaderMaterial({\n uniforms: uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader,\n })\n const plane = new PlaneGeometry(frame.width, frame.height)\n const mesh = new Mesh(plane, material)\n\n scene.add(mesh)\n\n //Label for light's name\n let labelCanvas, labelMesh\n\n if (doRenderLabel) {\n labelCanvas = document.createElement('canvas')\n\n const context = labelCanvas.getContext('2d')\n context.font = 'Bold 20px Arial'\n\n const labelWidth = context.measureText(light.name).width\n labelCanvas.width = labelWidth\n labelCanvas.height = 25 //25 to account for g, p, etc.\n\n context.font = 'Bold 20px Arial'\n context.fillStyle = 'rgba( 255, 0, 0, 1 )'\n context.fillText(light.name, 0, 20)\n\n const labelTexture = new Texture(labelCanvas)\n labelTexture.magFilter = LinearFilter\n labelTexture.minFilter = LinearFilter\n labelTexture.needsUpdate = true\n\n const labelMaterial = new MeshBasicMaterial({ map: labelTexture, side: DoubleSide })\n labelMaterial.transparent = true\n\n const labelPlane = new PlaneGeometry(labelCanvas.width, labelCanvas.height)\n labelMesh = new Mesh(labelPlane, labelMaterial)\n\n scene.add(labelMesh)\n }\n\n function resetPosition() {\n scope.position.set(scope.position.x, scope.position.y)\n }\n\n //- API\n // Set to false to disable displaying this shadow map\n this.enabled = true\n\n // Set the size of the displayed shadow map on the HUD\n this.size = {\n width: frame.width,\n height: frame.height,\n set: function (width, height) {\n this.width = width\n this.height = height\n\n mesh.scale.set(this.width / frame.width, this.height / frame.height, 1)\n\n //Reset the position as it is off when we scale stuff\n resetPosition()\n },\n }\n\n // Set the position of the displayed shadow map on the HUD\n this.position = {\n x: frame.x,\n y: frame.y,\n set: function (x, y) {\n this.x = x\n this.y = y\n\n const width = scope.size.width\n const height = scope.size.height\n\n mesh.position.set(-window.innerWidth / 2 + width / 2 + this.x, window.innerHeight / 2 - height / 2 - this.y, 0)\n\n if (doRenderLabel)\n labelMesh.position.set(mesh.position.x, mesh.position.y - scope.size.height / 2 + labelCanvas.height / 2, 0)\n },\n }\n\n this.render = function (renderer) {\n if (this.enabled) {\n //Because a light's .shadowMap is only initialised after the first render pass\n //we have to make sure the correct map is sent into the shader, otherwise we\n //always end up with the scene's first added shadow casting light's shadowMap\n //in the shader\n //See: https://github.com/mrdoob/three.js/issues/5932\n uniforms.tDiffuse.value = light.shadow.map.texture\n\n userAutoClearSetting = renderer.autoClear\n renderer.autoClear = false // To allow render overlay\n renderer.clearDepth()\n renderer.render(scene, camera)\n renderer.autoClear = userAutoClearSetting //Restore user's setting\n }\n }\n\n this.updateForWindowResize = function () {\n if (this.enabled) {\n camera.left = window.innerWidth / -2\n camera.right = window.innerWidth / 2\n camera.top = window.innerHeight / 2\n camera.bottom = window.innerHeight / -2\n camera.updateProjectionMatrix()\n\n this.update()\n }\n }\n\n this.update = function () {\n this.position.set(this.position.x, this.position.y)\n this.size.set(this.size.width, this.size.height)\n }\n\n //Force an update to set position/size\n this.update()\n }\n}\n\nexport { ShadowMapViewer }\n"],"names":["OrthographicCamera","Scene","UnpackDepthRGBAShader","UniformsUtils","ShaderMaterial","PlaneGeometry","Mesh","Texture","LinearFilter","MeshBasicMaterial","DoubleSide"],"mappings":"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"}