1 line
8.6 KiB
Plaintext
1 line
8.6 KiB
Plaintext
|
|
{"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\
|