Skip to content

Commit

Permalink
t
Browse files Browse the repository at this point in the history
  • Loading branch information
CodyJasonBennett committed May 26, 2023
1 parent b28d498 commit 1dd5869
Show file tree
Hide file tree
Showing 5 changed files with 343 additions and 355 deletions.
4 changes: 2 additions & 2 deletions src/postprocessing/AdaptiveToneMappingPass.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { WebGLRenderTarget, ShaderMaterial } from 'three'

import { Pass } from './Pass'
import { Pass, FullScreenQuad } from './Pass'

export class AdaptiveToneMappingPass extends Pass {
constructor(adaptive?: boolean, resolution?: number)
Expand All @@ -16,7 +16,7 @@ export class AdaptiveToneMappingPass extends Pass {
adaptLuminanceShader: object
materialAdaptiveLum: ShaderMaterial
materialToneMap: ShaderMaterial
fsQuad: object
fsQuad: FullScreenQuad

reset(): void
setAdaptive(adaptive: boolean): void
Expand Down
254 changes: 119 additions & 135 deletions src/postprocessing/AdaptiveToneMappingPass.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import {
LinearFilter,
LinearMipmapLinearFilter,
MeshBasicMaterial,
NoBlending,
RGBAFormat,
ShaderMaterial,
UniformsUtils,
WebGLRenderTarget,
} from 'three'
import { Pass, FullScreenQuad } from '../postprocessing/Pass'
import { Pass, FullScreenQuad } from './Pass'
import { CopyShader } from '../shaders/CopyShader'
import { LuminosityShader } from '../shaders/LuminosityShader'
import { ToneMapShader } from '../shaders/ToneMapShader'
Expand All @@ -21,112 +19,103 @@ import { ToneMapShader } from '../shaders/ToneMapShader'
* Full-screen tone-mapping shader based on http://www.graphics.cornell.edu/~jaf/publications/sig02_paper.pdf
*/

var AdaptiveToneMappingPass = function (adaptive, resolution) {
this.resolution = resolution !== undefined ? resolution : 256
this.needsInit = true
this.adaptive = adaptive !== undefined ? !!adaptive : true

this.luminanceRT = null
this.previousLuminanceRT = null
this.currentLuminanceRT = null

if (CopyShader === undefined) console.error('THREE.AdaptiveToneMappingPass relies on CopyShader')

var copyShader = CopyShader

this.copyUniforms = UniformsUtils.clone(copyShader.uniforms)

this.materialCopy = new ShaderMaterial({
uniforms: this.copyUniforms,
vertexShader: copyShader.vertexShader,
fragmentShader: copyShader.fragmentShader,
blending: NoBlending,
depthTest: false,
})

if (LuminosityShader === undefined) console.error('THREE.AdaptiveToneMappingPass relies on LuminosityShader')

this.materialLuminance = new ShaderMaterial({
uniforms: UniformsUtils.clone(LuminosityShader.uniforms),
vertexShader: LuminosityShader.vertexShader,
fragmentShader: LuminosityShader.fragmentShader,
blending: NoBlending,
})

this.adaptLuminanceShader = {
defines: {
MIP_LEVEL_1X1: (Math.log(this.resolution) / Math.log(2.0)).toFixed(1),
},
uniforms: {
lastLum: { value: null },
currentLum: { value: null },
minLuminance: { value: 0.01 },
delta: { value: 0.016 },
tau: { value: 1.0 },
},
vertexShader: [
'varying vec2 vUv;',

'void main() {',

' vUv = uv;',
' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',

'}',
].join('\n'),
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;',
'}',
].join('\n'),
}

this.materialAdaptiveLum = new ShaderMaterial({
uniforms: UniformsUtils.clone(this.adaptLuminanceShader.uniforms),
vertexShader: this.adaptLuminanceShader.vertexShader,
fragmentShader: this.adaptLuminanceShader.fragmentShader,
defines: Object.assign({}, this.adaptLuminanceShader.defines),
blending: NoBlending,
})

if (ToneMapShader === undefined) console.error('THREE.AdaptiveToneMappingPass relies on ToneMapShader')

this.materialToneMap = new ShaderMaterial({
uniforms: UniformsUtils.clone(ToneMapShader.uniforms),
vertexShader: ToneMapShader.vertexShader,
fragmentShader: ToneMapShader.fragmentShader,
blending: NoBlending,
})

this.fsQuad = new FullScreenQuad(null)
}
class AdaptiveToneMappingPass extends Pass {
constructor(adaptive, resolution) {
super()

this.resolution = resolution !== undefined ? resolution : 256
this.needsInit = true
this.adaptive = adaptive !== undefined ? !!adaptive : true

this.luminanceRT = null
this.previousLuminanceRT = null
this.currentLuminanceRT = null

const copyShader = CopyShader

this.copyUniforms = UniformsUtils.clone(copyShader.uniforms)

this.materialCopy = new ShaderMaterial({
uniforms: this.copyUniforms,
vertexShader: copyShader.vertexShader,
fragmentShader: copyShader.fragmentShader,
blending: NoBlending,
depthTest: false,
})

this.materialLuminance = new ShaderMaterial({
uniforms: UniformsUtils.clone(LuminosityShader.uniforms),
vertexShader: LuminosityShader.vertexShader,
fragmentShader: LuminosityShader.fragmentShader,
blending: NoBlending,
})

this.adaptLuminanceShader = {
defines: {
MIP_LEVEL_1X1: (Math.log(this.resolution) / Math.log(2.0)).toFixed(1),
},
uniforms: {
lastLum: { value: null },
currentLum: { value: null },
minLuminance: { value: 0.01 },
delta: { value: 0.016 },
tau: { value: 1.0 },
},
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;
}`,
}

AdaptiveToneMappingPass.prototype = Object.assign(Object.create(Pass.prototype), {
constructor: AdaptiveToneMappingPass,
this.materialAdaptiveLum = new ShaderMaterial({
uniforms: UniformsUtils.clone(this.adaptLuminanceShader.uniforms),
vertexShader: this.adaptLuminanceShader.vertexShader,
fragmentShader: this.adaptLuminanceShader.fragmentShader,
defines: Object.assign({}, this.adaptLuminanceShader.defines),
blending: NoBlending,
})

this.materialToneMap = new ShaderMaterial({
uniforms: UniformsUtils.clone(ToneMapShader.uniforms),
vertexShader: ToneMapShader.vertexShader,
fragmentShader: ToneMapShader.fragmentShader,
blending: NoBlending,
})

this.fsQuad = new FullScreenQuad(null)
}

render: function (renderer, writeBuffer, readBuffer, deltaTime /*, maskActive*/) {
render(renderer, writeBuffer, readBuffer, deltaTime /*, maskActive*/) {
if (this.needsInit) {
this.reset(renderer)

Expand Down Expand Up @@ -172,9 +161,9 @@ AdaptiveToneMappingPass.prototype = Object.assign(Object.create(Pass.prototype),

this.fsQuad.render(renderer)
}
},
}

reset: function () {
reset() {
// render targets
if (this.luminanceRT) {
this.luminanceRT.dispose()
Expand All @@ -188,23 +177,18 @@ AdaptiveToneMappingPass.prototype = Object.assign(Object.create(Pass.prototype),
this.previousLuminanceRT.dispose()
}

var pars = {
minFilter: LinearFilter,
magFilter: LinearFilter,
format: RGBAFormat,
} // was RGB format. changed to RGBA format. see discussion in #8415 / #8450

this.luminanceRT = new WebGLRenderTarget(this.resolution, this.resolution, pars)
this.luminanceRT = new WebGLRenderTarget(this.resolution, this.resolution)
this.luminanceRT.texture.name = 'AdaptiveToneMappingPass.l'
this.luminanceRT.texture.generateMipmaps = false

this.previousLuminanceRT = new WebGLRenderTarget(this.resolution, this.resolution, pars)
this.previousLuminanceRT = new WebGLRenderTarget(this.resolution, this.resolution)
this.previousLuminanceRT.texture.name = 'AdaptiveToneMappingPass.pl'
this.previousLuminanceRT.texture.generateMipmaps = false

// We only need mipmapping for the current luminosity because we want a down-sampled version to sample in our adaptive shader
pars.minFilter = LinearMipmapLinearFilter
pars.generateMipmaps = true

const pars = { minFilter: LinearMipmapLinearFilter, generateMipmaps: true }

this.currentLuminanceRT = new WebGLRenderTarget(this.resolution, this.resolution, pars)
this.currentLuminanceRT.texture.name = 'AdaptiveToneMappingPass.cl'

Expand All @@ -221,9 +205,9 @@ AdaptiveToneMappingPass.prototype = Object.assign(Object.create(Pass.prototype),
// renderer.render( this.scene, this.camera, this.luminanceRT );
// renderer.render( this.scene, this.camera, this.previousLuminanceRT );
// renderer.render( this.scene, this.camera, this.currentLuminanceRT );
},
}

setAdaptive: function (adaptive) {
setAdaptive(adaptive) {
if (adaptive) {
this.adaptive = true
this.materialToneMap.defines['ADAPTED_LUMINANCE'] = ''
Expand All @@ -235,40 +219,40 @@ AdaptiveToneMappingPass.prototype = Object.assign(Object.create(Pass.prototype),
}

this.materialToneMap.needsUpdate = true
},
}

setAdaptionRate: function (rate) {
setAdaptionRate(rate) {
if (rate) {
this.materialAdaptiveLum.uniforms.tau.value = Math.abs(rate)
}
},
}

setMinLuminance: function (minLum) {
setMinLuminance(minLum) {
if (minLum) {
this.materialToneMap.uniforms.minLuminance.value = minLum
this.materialAdaptiveLum.uniforms.minLuminance.value = minLum
}
},
}

setMaxLuminance: function (maxLum) {
setMaxLuminance(maxLum) {
if (maxLum) {
this.materialToneMap.uniforms.maxLuminance.value = maxLum
}
},
}

setAverageLuminance: function (avgLum) {
setAverageLuminance(avgLum) {
if (avgLum) {
this.materialToneMap.uniforms.averageLuminance.value = avgLum
}
},
}

setMiddleGrey: function (middleGrey) {
setMiddleGrey(middleGrey) {
if (middleGrey) {
this.materialToneMap.uniforms.middleGrey.value = middleGrey
}
},
}

dispose: function () {
dispose() {
if (this.luminanceRT) {
this.luminanceRT.dispose()
}
Expand Down Expand Up @@ -296,7 +280,7 @@ AdaptiveToneMappingPass.prototype = Object.assign(Object.create(Pass.prototype),
if (this.materialToneMap) {
this.materialToneMap.dispose()
}
},
})
}
}

export { AdaptiveToneMappingPass }
Loading

0 comments on commit 1dd5869

Please sign in to comment.