UNPKG

three-stdlib

Version:

stand-alone library of threejs examples

220 lines (210 loc) 8.17 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const THREE = require("three"); const Pass = require("./Pass.cjs"); const CopyShader = require("../shaders/CopyShader.cjs"); const LuminosityShader = require("../shaders/LuminosityShader.cjs"); const ToneMapShader = require("../shaders/ToneMapShader.cjs"); class AdaptiveToneMappingPass extends Pass.Pass { constructor(adaptive, resolution) { super(); this.resolution = resolution !== void 0 ? resolution : 256; this.needsInit = true; this.adaptive = adaptive !== void 0 ? !!adaptive : true; this.luminanceRT = null; this.previousLuminanceRT = null; this.currentLuminanceRT = null; const copyShader = CopyShader.CopyShader; this.copyUniforms = THREE.UniformsUtils.clone(copyShader.uniforms); this.materialCopy = new THREE.ShaderMaterial({ uniforms: this.copyUniforms, vertexShader: copyShader.vertexShader, fragmentShader: copyShader.fragmentShader, blending: THREE.NoBlending, depthTest: false }); this.materialLuminance = new THREE.ShaderMaterial({ uniforms: THREE.UniformsUtils.clone(LuminosityShader.LuminosityShader.uniforms), vertexShader: LuminosityShader.LuminosityShader.vertexShader, fragmentShader: LuminosityShader.LuminosityShader.fragmentShader, blending: THREE.NoBlending }); this.adaptLuminanceShader = { defines: { MIP_LEVEL_1X1: (Math.log(this.resolution) / Math.log(2)).toFixed(1) }, uniforms: { lastLum: { value: null }, currentLum: { value: null }, minLuminance: { value: 0.01 }, delta: { value: 0.016 }, tau: { value: 1 } }, vertexShader: `varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, fragmentShader: `varying vec2 vUv; uniform sampler2D lastLum; uniform sampler2D currentLum; uniform float minLuminance; uniform float delta; uniform float tau; void main() { vec4 lastLum = texture2D( lastLum, vUv, MIP_LEVEL_1X1 ); vec4 currentLum = texture2D( currentLum, vUv, MIP_LEVEL_1X1 ); float fLastLum = max( minLuminance, lastLum.r ); float fCurrentLum = max( minLuminance, currentLum.r ); //The adaption seems to work better in extreme lighting differences //if the input luminance is squared. fCurrentLum *= fCurrentLum; // Adapt the luminance using Pattanaik's technique float fAdaptedLum = fLastLum + (fCurrentLum - fLastLum) * (1.0 - exp(-delta * tau)); // "fAdaptedLum = sqrt(fAdaptedLum); gl_FragColor.r = fAdaptedLum; }` }; this.materialAdaptiveLum = new THREE.ShaderMaterial({ uniforms: THREE.UniformsUtils.clone(this.adaptLuminanceShader.uniforms), vertexShader: this.adaptLuminanceShader.vertexShader, fragmentShader: this.adaptLuminanceShader.fragmentShader, defines: Object.assign({}, this.adaptLuminanceShader.defines), blending: THREE.NoBlending }); this.materialToneMap = new THREE.ShaderMaterial({ uniforms: THREE.UniformsUtils.clone(ToneMapShader.ToneMapShader.uniforms), vertexShader: ToneMapShader.ToneMapShader.vertexShader, fragmentShader: ToneMapShader.ToneMapShader.fragmentShader, blending: THREE.NoBlending }); this.fsQuad = new Pass.FullScreenQuad(null); } render(renderer, writeBuffer, readBuffer, deltaTime) { if (this.needsInit) { this.reset(renderer); this.luminanceRT.texture.type = readBuffer.texture.type; this.previousLuminanceRT.texture.type = readBuffer.texture.type; this.currentLuminanceRT.texture.type = readBuffer.texture.type; this.needsInit = false; } if (this.adaptive) { this.fsQuad.material = this.materialLuminance; this.materialLuminance.uniforms.tDiffuse.value = readBuffer.texture; renderer.setRenderTarget(this.currentLuminanceRT); this.fsQuad.render(renderer); this.fsQuad.material = this.materialAdaptiveLum; this.materialAdaptiveLum.uniforms.delta.value = deltaTime; this.materialAdaptiveLum.uniforms.lastLum.value = this.previousLuminanceRT.texture; this.materialAdaptiveLum.uniforms.currentLum.value = this.currentLuminanceRT.texture; renderer.setRenderTarget(this.luminanceRT); this.fsQuad.render(renderer); this.fsQuad.material = this.materialCopy; this.copyUniforms.tDiffuse.value = this.luminanceRT.texture; renderer.setRenderTarget(this.previousLuminanceRT); this.fsQuad.render(renderer); } this.fsQuad.material = this.materialToneMap; this.materialToneMap.uniforms.tDiffuse.value = readBuffer.texture; if (this.renderToScreen) { renderer.setRenderTarget(null); this.fsQuad.render(renderer); } else { renderer.setRenderTarget(writeBuffer); if (this.clear) renderer.clear(); this.fsQuad.render(renderer); } } reset() { if (this.luminanceRT) { this.luminanceRT.dispose(); } if (this.currentLuminanceRT) { this.currentLuminanceRT.dispose(); } if (this.previousLuminanceRT) { this.previousLuminanceRT.dispose(); } this.luminanceRT = new THREE.WebGLRenderTarget(this.resolution, this.resolution); this.luminanceRT.texture.name = "AdaptiveToneMappingPass.l"; this.luminanceRT.texture.generateMipmaps = false; this.previousLuminanceRT = new THREE.WebGLRenderTarget(this.resolution, this.resolution); this.previousLuminanceRT.texture.name = "AdaptiveToneMappingPass.pl"; this.previousLuminanceRT.texture.generateMipmaps = false; const pars = { minFilter: THREE.LinearMipmapLinearFilter, generateMipmaps: true }; this.currentLuminanceRT = new THREE.WebGLRenderTarget(this.resolution, this.resolution, pars); this.currentLuminanceRT.texture.name = "AdaptiveToneMappingPass.cl"; if (this.adaptive) { this.materialToneMap.defines["ADAPTED_LUMINANCE"] = ""; this.materialToneMap.uniforms.luminanceMap.value = this.luminanceRT.texture; } this.fsQuad.material = new THREE.MeshBasicMaterial({ color: 7829367 }); this.materialLuminance.needsUpdate = true; this.materialAdaptiveLum.needsUpdate = true; this.materialToneMap.needsUpdate = true; } setAdaptive(adaptive) { if (adaptive) { this.adaptive = true; this.materialToneMap.defines["ADAPTED_LUMINANCE"] = ""; this.materialToneMap.uniforms.luminanceMap.value = this.luminanceRT.texture; } else { this.adaptive = false; delete this.materialToneMap.defines["ADAPTED_LUMINANCE"]; this.materialToneMap.uniforms.luminanceMap.value = null; } this.materialToneMap.needsUpdate = true; } setAdaptionRate(rate) { if (rate) { this.materialAdaptiveLum.uniforms.tau.value = Math.abs(rate); } } setMinLuminance(minLum) { if (minLum) { this.materialToneMap.uniforms.minLuminance.value = minLum; this.materialAdaptiveLum.uniforms.minLuminance.value = minLum; } } setMaxLuminance(maxLum) { if (maxLum) { this.materialToneMap.uniforms.maxLuminance.value = maxLum; } } setAverageLuminance(avgLum) { if (avgLum) { this.materialToneMap.uniforms.averageLuminance.value = avgLum; } } setMiddleGrey(middleGrey) { if (middleGrey) { this.materialToneMap.uniforms.middleGrey.value = middleGrey; } } dispose() { if (this.luminanceRT) { this.luminanceRT.dispose(); } if (this.previousLuminanceRT) { this.previousLuminanceRT.dispose(); } if (this.currentLuminanceRT) { this.currentLuminanceRT.dispose(); } if (this.materialLuminance) { this.materialLuminance.dispose(); } if (this.materialAdaptiveLum) { this.materialAdaptiveLum.dispose(); } if (this.materialCopy) { this.materialCopy.dispose(); } if (this.materialToneMap) { this.materialToneMap.dispose(); } } } exports.AdaptiveToneMappingPass = AdaptiveToneMappingPass; //# sourceMappingURL=AdaptiveToneMappingPass.cjs.map