{"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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"}