{"version":3,"file":"AdaptiveToneMappingPass.cjs","sources":["../../src/postprocessing/AdaptiveToneMappingPass.js"],"sourcesContent":["import {\n LinearMipmapLinearFilter,\n MeshBasicMaterial,\n NoBlending,\n ShaderMaterial,\n UniformsUtils,\n WebGLRenderTarget,\n} from 'three'\nimport { Pass, FullScreenQuad } from './Pass'\nimport { CopyShader } from '../shaders/CopyShader'\nimport { LuminosityShader } from '../shaders/LuminosityShader'\nimport { ToneMapShader } from '../shaders/ToneMapShader'\n\n/**\n * Generate a texture that represents the luminosity of the current scene, adapted over time\n * to simulate the optic nerve responding to the amount of light it is receiving.\n * Based on a GDC2007 presentation by Wolfgang Engel titled \"Post-Processing Pipeline\"\n *\n * Full-screen tone-mapping shader based on http://www.graphics.cornell.edu/~jaf/publications/sig02_paper.pdf\n */\n\nclass AdaptiveToneMappingPass extends Pass {\n constructor(adaptive, resolution) {\n super()\n\n this.resolution = resolution !== undefined ? resolution : 256\n this.needsInit = true\n this.adaptive = adaptive !== undefined ? !!adaptive : true\n\n this.luminanceRT = null\n this.previousLuminanceRT = null\n this.currentLuminanceRT = null\n\n const copyShader = CopyShader\n\n this.copyUniforms = UniformsUtils.clone(copyShader.uniforms)\n\n this.materialCopy = new ShaderMaterial({\n uniforms: this.copyUniforms,\n vertexShader: copyShader.vertexShader,\n fragmentShader: copyShader.fragmentShader,\n blending: NoBlending,\n depthTest: false,\n })\n\n this.materialLuminance = new ShaderMaterial({\n uniforms: UniformsUtils.clone(LuminosityShader.uniforms),\n vertexShader: LuminosityShader.vertexShader,\n fragmentShader: LuminosityShader.fragmentShader,\n blending: NoBlending,\n })\n\n this.adaptLuminanceShader = {\n defines: {\n MIP_LEVEL_1X1: (Math.log(this.resolution) / Math.log(2.0)).toFixed(1),\n },\n uniforms: {\n lastLum: { value: null },\n currentLum: { value: null },\n minLuminance: { value: 0.01 },\n delta: { value: 0.016 },\n tau: { value: 1.0 },\n },\n vertexShader: `varying vec2 vUv;\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvUv = uv;\n\t\t\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t\t\t\t}`,\n\n fragmentShader: `varying vec2 vUv;\n\n\t\t\t\tuniform sampler2D lastLum;\n\t\t\t\tuniform sampler2D currentLum;\n\t\t\t\tuniform float minLuminance;\n\t\t\t\tuniform float delta;\n\t\t\t\tuniform float tau;\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvec4 lastLum = texture2D( lastLum, vUv, MIP_LEVEL_1X1 );\n\t\t\t\t\tvec4 currentLum = texture2D( currentLum, vUv, MIP_LEVEL_1X1 );\n\n\t\t\t\t\tfloat fLastLum = max( minLuminance, lastLum.r );\n\t\t\t\t\tfloat fCurrentLum = max( minLuminance, currentLum.r );\n\n\t\t\t\t\t//The adaption seems to work better in extreme lighting differences\n\t\t\t\t\t//if the input luminance is squared.\n\t\t\t\t\tfCurrentLum *= fCurrentLum;\n\n\t\t\t\t\t// Adapt the luminance using Pattanaik's technique\n\t\t\t\t\tfloat fAdaptedLum = fLastLum + (fCurrentLum - fLastLum) * (1.0 - exp(-delta * tau));\n\t\t\t\t\t// \"fAdaptedLum = sqrt(fAdaptedLum);\n\t\t\t\t\tgl_FragColor.r = fAdaptedLum;\n\t\t\t\t}`,\n }\n\n this.materialAdaptiveLum = new ShaderMaterial({\n uniforms: UniformsUtils.clone(this.adaptLuminanceShader.uniforms),\n vertexShader: this.adaptLuminanceShader.vertexShader,\n fragmentShader: this.adaptLuminanceShader.fragmentShader,\n defines: Object.assign({}, this.adaptLuminanceShader.defines),\n blending: NoBlending,\n })\n\n this.materialToneMap = new ShaderMaterial({\n uniforms: UniformsUtils.clone(ToneMapShader.uniforms),\n vertexShader: ToneMapShader.vertexShader,\n fragmentShader: ToneMapShader.fragmentShader,\n blending: NoBlending,\n })\n\n this.fsQuad = new FullScreenQuad(null)\n }\n\n render(renderer, writeBuffer, readBuffer, deltaTime /*, maskActive*/) {\n if (this.needsInit) {\n this.reset(renderer)\n\n this.luminanceRT.texture.type = readBuffer.texture.type\n this.previousLuminanceRT.texture.type = readBuffer.texture.type\n this.currentLuminanceRT.texture.type = readBuffer.texture.type\n this.needsInit = false\n }\n\n if (this.adaptive) {\n //Render the luminance of the current scene into a render target with mipmapping enabled\n this.fsQuad.material = this.materialLuminance\n this.materialLuminance.uniforms.tDiffuse.value = readBuffer.texture\n renderer.setRenderTarget(this.currentLuminanceRT)\n this.fsQuad.render(renderer)\n\n //Use the new luminance values, the previous luminance and the frame delta to\n //adapt the luminance over time.\n this.fsQuad.material = this.materialAdaptiveLum\n this.materialAdaptiveLum.uniforms.delta.value = deltaTime\n this.materialAdaptiveLum.uniforms.lastLum.value = this.previousLuminanceRT.texture\n this.materialAdaptiveLum.uniforms.currentLum.value = this.currentLuminanceRT.texture\n renderer.setRenderTarget(this.luminanceRT)\n this.fsQuad.render(renderer)\n\n //Copy the new adapted luminance value so that it can be used by the next frame.\n this.fsQuad.material = this.materialCopy\n this.copyUniforms.tDiffuse.value = this.luminanceRT.texture\n renderer.setRenderTarget(this.previousLuminanceRT)\n this.fsQuad.render(renderer)\n }\n\n this.fsQuad.material = this.materialToneMap\n this.materialToneMap.uniforms.tDiffuse.value = readBuffer.texture\n\n if (this.renderToScreen) {\n renderer.setRenderTarget(null)\n this.fsQuad.render(renderer)\n } else {\n renderer.setRenderTarget(writeBuffer)\n\n if (this.clear) renderer.clear()\n\n this.fsQuad.render(renderer)\n }\n }\n\n reset() {\n // render targets\n if (this.luminanceRT) {\n this.luminanceRT.dispose()\n }\n\n if (this.currentLuminanceRT) {\n this.currentLuminanceRT.dispose()\n }\n\n if (this.previousLuminanceRT) {\n this.previousLuminanceRT.dispose()\n }\n\n this.luminanceRT = new WebGLRenderTarget(this.resolution, this.resolution)\n this.luminanceRT.texture.name = 'AdaptiveToneMappingPass.l'\n this.luminanceRT.texture.generateMipmaps = false\n\n this.previousLuminanceRT = new WebGLRenderTarget(this.resolution, this.resolution)\n this.previousLuminanceRT.texture.name = 'AdaptiveToneMappingPass.pl'\n this.previousLuminanceRT.texture.generateMipmaps = false\n\n // We only need mipmapping for the current luminosity because we want a down-sampled version to sample in our adaptive shader\n\n const pars = { minFilter: LinearMipmapLinearFilter, generateMipmaps: true }\n\n this.currentLuminanceRT = new WebGLRenderTarget(this.resolution, this.resolution, pars)\n this.currentLuminanceRT.texture.name = 'AdaptiveToneMappingPass.cl'\n\n if (this.adaptive) {\n this.materialToneMap.defines['ADAPTED_LUMINANCE'] = ''\n this.materialToneMap.uniforms.luminanceMap.value = this.luminanceRT.texture\n }\n\n //Put something in the adaptive luminance texture so that the scene can render initially\n this.fsQuad.material = new MeshBasicMaterial({ color: 0x777777 })\n this.materialLuminance.needsUpdate = true\n this.materialAdaptiveLum.needsUpdate = true\n this.materialToneMap.needsUpdate = true\n // renderer.render( this.scene, this.camera, this.luminanceRT );\n // renderer.render( this.scene, this.camera, this.previousLuminanceRT );\n // renderer.render( this.scene, this.camera, this.currentLuminanceRT );\n }\n\n setAdaptive(adaptive) {\n if (adaptive) {\n this.adaptive = true\n this.materialToneMap.defines['ADAPTED_LUMINANCE'] = ''\n this.materialToneMap.uniforms.luminanceMap.value = this.luminanceRT.texture\n } else {\n this.adaptive = false\n delete this.materialToneMap.defines['ADAPTED_LUMINANCE']\n this.materialToneMap.uniforms.luminanceMap.value = null\n }\n\n this.materialToneMap.needsUpdate = true\n }\n\n setAdaptionRate(rate) {\n if (rate) {\n this.materialAdaptiveLum.uniforms.tau.value = Math.abs(rate)\n }\n }\n\n setMinLuminance(minLum) {\n if (minLum) {\n this.materialToneMap.uniforms.minLuminance.value = minLum\n this.materialAdaptiveLum.uniforms.minLuminance.value = minLum\n }\n }\n\n setMaxLuminance(maxLum) {\n if (maxLum) {\n this.materialToneMap.uniforms.maxLuminance.value = maxLum\n }\n }\n\n setAverageLuminance(avgLum) {\n if (avgLum) {\n this.materialToneMap.uniforms.averageLuminance.value = avgLum\n }\n }\n\n setMiddleGrey(middleGrey) {\n if (middleGrey) {\n this.materialToneMap.uniforms.middleGrey.value = middleGrey\n }\n }\n\n dispose() {\n if (this.luminanceRT) {\n this.luminanceRT.dispose()\n }\n\n if (this.previousLuminanceRT) {\n this.previousLuminanceRT.dispose()\n }\n\n if (this.currentLuminanceRT) {\n this.currentLuminanceRT.dispose()\n }\n\n if (this.materialLuminance) {\n this.materialLuminance.dispose()\n }\n\n if (this.materialAdaptiveLum) {\n this.materialAdaptiveLum.dispose()\n }\n\n if (this.materialCopy) {\n this.materialCopy.dispose()\n }\n\n if (this.materialToneMap) {\n this.materialToneMap.dispose()\n }\n }\n}\n\nexport { AdaptiveToneMappingPass }\n"],"names":["Pass","CopyShader","UniformsUtils","ShaderMaterial","NoBlending","LuminosityShader","ToneMapShader","FullScreenQuad","WebGLRenderTarget","LinearMipmapLinearFilter","MeshBasicMaterial"],"mappings":"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"}