Skip to content

Commit 1dd5869

Browse files
t
1 parent b28d498 commit 1dd5869

File tree

5 files changed

+343
-355
lines changed

5 files changed

+343
-355
lines changed

src/postprocessing/AdaptiveToneMappingPass.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { WebGLRenderTarget, ShaderMaterial } from 'three'
22

3-
import { Pass } from './Pass'
3+
import { Pass, FullScreenQuad } from './Pass'
44

55
export class AdaptiveToneMappingPass extends Pass {
66
constructor(adaptive?: boolean, resolution?: number)
@@ -16,7 +16,7 @@ export class AdaptiveToneMappingPass extends Pass {
1616
adaptLuminanceShader: object
1717
materialAdaptiveLum: ShaderMaterial
1818
materialToneMap: ShaderMaterial
19-
fsQuad: object
19+
fsQuad: FullScreenQuad
2020

2121
reset(): void
2222
setAdaptive(adaptive: boolean): void
Lines changed: 119 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
import {
2-
LinearFilter,
32
LinearMipmapLinearFilter,
43
MeshBasicMaterial,
54
NoBlending,
6-
RGBAFormat,
75
ShaderMaterial,
86
UniformsUtils,
97
WebGLRenderTarget,
108
} from 'three'
11-
import { Pass, FullScreenQuad } from '../postprocessing/Pass'
9+
import { Pass, FullScreenQuad } from './Pass'
1210
import { CopyShader } from '../shaders/CopyShader'
1311
import { LuminosityShader } from '../shaders/LuminosityShader'
1412
import { ToneMapShader } from '../shaders/ToneMapShader'
@@ -21,112 +19,103 @@ import { ToneMapShader } from '../shaders/ToneMapShader'
2119
* Full-screen tone-mapping shader based on http://www.graphics.cornell.edu/~jaf/publications/sig02_paper.pdf
2220
*/
2321

24-
var AdaptiveToneMappingPass = function (adaptive, resolution) {
25-
this.resolution = resolution !== undefined ? resolution : 256
26-
this.needsInit = true
27-
this.adaptive = adaptive !== undefined ? !!adaptive : true
28-
29-
this.luminanceRT = null
30-
this.previousLuminanceRT = null
31-
this.currentLuminanceRT = null
32-
33-
if (CopyShader === undefined) console.error('THREE.AdaptiveToneMappingPass relies on CopyShader')
34-
35-
var copyShader = CopyShader
36-
37-
this.copyUniforms = UniformsUtils.clone(copyShader.uniforms)
38-
39-
this.materialCopy = new ShaderMaterial({
40-
uniforms: this.copyUniforms,
41-
vertexShader: copyShader.vertexShader,
42-
fragmentShader: copyShader.fragmentShader,
43-
blending: NoBlending,
44-
depthTest: false,
45-
})
46-
47-
if (LuminosityShader === undefined) console.error('THREE.AdaptiveToneMappingPass relies on LuminosityShader')
48-
49-
this.materialLuminance = new ShaderMaterial({
50-
uniforms: UniformsUtils.clone(LuminosityShader.uniforms),
51-
vertexShader: LuminosityShader.vertexShader,
52-
fragmentShader: LuminosityShader.fragmentShader,
53-
blending: NoBlending,
54-
})
55-
56-
this.adaptLuminanceShader = {
57-
defines: {
58-
MIP_LEVEL_1X1: (Math.log(this.resolution) / Math.log(2.0)).toFixed(1),
59-
},
60-
uniforms: {
61-
lastLum: { value: null },
62-
currentLum: { value: null },
63-
minLuminance: { value: 0.01 },
64-
delta: { value: 0.016 },
65-
tau: { value: 1.0 },
66-
},
67-
vertexShader: [
68-
'varying vec2 vUv;',
69-
70-
'void main() {',
71-
72-
' vUv = uv;',
73-
' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
74-
75-
'}',
76-
].join('\n'),
77-
fragmentShader: [
78-
'varying vec2 vUv;',
79-
80-
'uniform sampler2D lastLum;',
81-
'uniform sampler2D currentLum;',
82-
'uniform float minLuminance;',
83-
'uniform float delta;',
84-
'uniform float tau;',
85-
86-
'void main() {',
87-
88-
' vec4 lastLum = texture2D( lastLum, vUv, MIP_LEVEL_1X1 );',
89-
' vec4 currentLum = texture2D( currentLum, vUv, MIP_LEVEL_1X1 );',
90-
91-
' float fLastLum = max( minLuminance, lastLum.r );',
92-
' float fCurrentLum = max( minLuminance, currentLum.r );',
93-
94-
//The adaption seems to work better in extreme lighting differences
95-
//if the input luminance is squared.
96-
' fCurrentLum *= fCurrentLum;',
97-
98-
// Adapt the luminance using Pattanaik's technique
99-
' float fAdaptedLum = fLastLum + (fCurrentLum - fLastLum) * (1.0 - exp(-delta * tau));',
100-
// "fAdaptedLum = sqrt(fAdaptedLum);",
101-
' gl_FragColor.r = fAdaptedLum;',
102-
'}',
103-
].join('\n'),
104-
}
105-
106-
this.materialAdaptiveLum = new ShaderMaterial({
107-
uniforms: UniformsUtils.clone(this.adaptLuminanceShader.uniforms),
108-
vertexShader: this.adaptLuminanceShader.vertexShader,
109-
fragmentShader: this.adaptLuminanceShader.fragmentShader,
110-
defines: Object.assign({}, this.adaptLuminanceShader.defines),
111-
blending: NoBlending,
112-
})
113-
114-
if (ToneMapShader === undefined) console.error('THREE.AdaptiveToneMappingPass relies on ToneMapShader')
115-
116-
this.materialToneMap = new ShaderMaterial({
117-
uniforms: UniformsUtils.clone(ToneMapShader.uniforms),
118-
vertexShader: ToneMapShader.vertexShader,
119-
fragmentShader: ToneMapShader.fragmentShader,
120-
blending: NoBlending,
121-
})
122-
123-
this.fsQuad = new FullScreenQuad(null)
124-
}
22+
class AdaptiveToneMappingPass extends Pass {
23+
constructor(adaptive, resolution) {
24+
super()
25+
26+
this.resolution = resolution !== undefined ? resolution : 256
27+
this.needsInit = true
28+
this.adaptive = adaptive !== undefined ? !!adaptive : true
29+
30+
this.luminanceRT = null
31+
this.previousLuminanceRT = null
32+
this.currentLuminanceRT = null
33+
34+
const copyShader = CopyShader
35+
36+
this.copyUniforms = UniformsUtils.clone(copyShader.uniforms)
37+
38+
this.materialCopy = new ShaderMaterial({
39+
uniforms: this.copyUniforms,
40+
vertexShader: copyShader.vertexShader,
41+
fragmentShader: copyShader.fragmentShader,
42+
blending: NoBlending,
43+
depthTest: false,
44+
})
45+
46+
this.materialLuminance = new ShaderMaterial({
47+
uniforms: UniformsUtils.clone(LuminosityShader.uniforms),
48+
vertexShader: LuminosityShader.vertexShader,
49+
fragmentShader: LuminosityShader.fragmentShader,
50+
blending: NoBlending,
51+
})
52+
53+
this.adaptLuminanceShader = {
54+
defines: {
55+
MIP_LEVEL_1X1: (Math.log(this.resolution) / Math.log(2.0)).toFixed(1),
56+
},
57+
uniforms: {
58+
lastLum: { value: null },
59+
currentLum: { value: null },
60+
minLuminance: { value: 0.01 },
61+
delta: { value: 0.016 },
62+
tau: { value: 1.0 },
63+
},
64+
vertexShader: `varying vec2 vUv;
65+
66+
void main() {
67+
68+
vUv = uv;
69+
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
70+
71+
}`,
72+
73+
fragmentShader: `varying vec2 vUv;
74+
75+
uniform sampler2D lastLum;
76+
uniform sampler2D currentLum;
77+
uniform float minLuminance;
78+
uniform float delta;
79+
uniform float tau;
80+
81+
void main() {
82+
83+
vec4 lastLum = texture2D( lastLum, vUv, MIP_LEVEL_1X1 );
84+
vec4 currentLum = texture2D( currentLum, vUv, MIP_LEVEL_1X1 );
85+
86+
float fLastLum = max( minLuminance, lastLum.r );
87+
float fCurrentLum = max( minLuminance, currentLum.r );
88+
89+
//The adaption seems to work better in extreme lighting differences
90+
//if the input luminance is squared.
91+
fCurrentLum *= fCurrentLum;
92+
93+
// Adapt the luminance using Pattanaik's technique
94+
float fAdaptedLum = fLastLum + (fCurrentLum - fLastLum) * (1.0 - exp(-delta * tau));
95+
// "fAdaptedLum = sqrt(fAdaptedLum);
96+
gl_FragColor.r = fAdaptedLum;
97+
}`,
98+
}
12599

126-
AdaptiveToneMappingPass.prototype = Object.assign(Object.create(Pass.prototype), {
127-
constructor: AdaptiveToneMappingPass,
100+
this.materialAdaptiveLum = new ShaderMaterial({
101+
uniforms: UniformsUtils.clone(this.adaptLuminanceShader.uniforms),
102+
vertexShader: this.adaptLuminanceShader.vertexShader,
103+
fragmentShader: this.adaptLuminanceShader.fragmentShader,
104+
defines: Object.assign({}, this.adaptLuminanceShader.defines),
105+
blending: NoBlending,
106+
})
107+
108+
this.materialToneMap = new ShaderMaterial({
109+
uniforms: UniformsUtils.clone(ToneMapShader.uniforms),
110+
vertexShader: ToneMapShader.vertexShader,
111+
fragmentShader: ToneMapShader.fragmentShader,
112+
blending: NoBlending,
113+
})
114+
115+
this.fsQuad = new FullScreenQuad(null)
116+
}
128117

129-
render: function (renderer, writeBuffer, readBuffer, deltaTime /*, maskActive*/) {
118+
render(renderer, writeBuffer, readBuffer, deltaTime /*, maskActive*/) {
130119
if (this.needsInit) {
131120
this.reset(renderer)
132121

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

173162
this.fsQuad.render(renderer)
174163
}
175-
},
164+
}
176165

177-
reset: function () {
166+
reset() {
178167
// render targets
179168
if (this.luminanceRT) {
180169
this.luminanceRT.dispose()
@@ -188,23 +177,18 @@ AdaptiveToneMappingPass.prototype = Object.assign(Object.create(Pass.prototype),
188177
this.previousLuminanceRT.dispose()
189178
}
190179

191-
var pars = {
192-
minFilter: LinearFilter,
193-
magFilter: LinearFilter,
194-
format: RGBAFormat,
195-
} // was RGB format. changed to RGBA format. see discussion in #8415 / #8450
196-
197-
this.luminanceRT = new WebGLRenderTarget(this.resolution, this.resolution, pars)
180+
this.luminanceRT = new WebGLRenderTarget(this.resolution, this.resolution)
198181
this.luminanceRT.texture.name = 'AdaptiveToneMappingPass.l'
199182
this.luminanceRT.texture.generateMipmaps = false
200183

201-
this.previousLuminanceRT = new WebGLRenderTarget(this.resolution, this.resolution, pars)
184+
this.previousLuminanceRT = new WebGLRenderTarget(this.resolution, this.resolution)
202185
this.previousLuminanceRT.texture.name = 'AdaptiveToneMappingPass.pl'
203186
this.previousLuminanceRT.texture.generateMipmaps = false
204187

205188
// We only need mipmapping for the current luminosity because we want a down-sampled version to sample in our adaptive shader
206-
pars.minFilter = LinearMipmapLinearFilter
207-
pars.generateMipmaps = true
189+
190+
const pars = { minFilter: LinearMipmapLinearFilter, generateMipmaps: true }
191+
208192
this.currentLuminanceRT = new WebGLRenderTarget(this.resolution, this.resolution, pars)
209193
this.currentLuminanceRT.texture.name = 'AdaptiveToneMappingPass.cl'
210194

@@ -221,9 +205,9 @@ AdaptiveToneMappingPass.prototype = Object.assign(Object.create(Pass.prototype),
221205
// renderer.render( this.scene, this.camera, this.luminanceRT );
222206
// renderer.render( this.scene, this.camera, this.previousLuminanceRT );
223207
// renderer.render( this.scene, this.camera, this.currentLuminanceRT );
224-
},
208+
}
225209

226-
setAdaptive: function (adaptive) {
210+
setAdaptive(adaptive) {
227211
if (adaptive) {
228212
this.adaptive = true
229213
this.materialToneMap.defines['ADAPTED_LUMINANCE'] = ''
@@ -235,40 +219,40 @@ AdaptiveToneMappingPass.prototype = Object.assign(Object.create(Pass.prototype),
235219
}
236220

237221
this.materialToneMap.needsUpdate = true
238-
},
222+
}
239223

240-
setAdaptionRate: function (rate) {
224+
setAdaptionRate(rate) {
241225
if (rate) {
242226
this.materialAdaptiveLum.uniforms.tau.value = Math.abs(rate)
243227
}
244-
},
228+
}
245229

246-
setMinLuminance: function (minLum) {
230+
setMinLuminance(minLum) {
247231
if (minLum) {
248232
this.materialToneMap.uniforms.minLuminance.value = minLum
249233
this.materialAdaptiveLum.uniforms.minLuminance.value = minLum
250234
}
251-
},
235+
}
252236

253-
setMaxLuminance: function (maxLum) {
237+
setMaxLuminance(maxLum) {
254238
if (maxLum) {
255239
this.materialToneMap.uniforms.maxLuminance.value = maxLum
256240
}
257-
},
241+
}
258242

259-
setAverageLuminance: function (avgLum) {
243+
setAverageLuminance(avgLum) {
260244
if (avgLum) {
261245
this.materialToneMap.uniforms.averageLuminance.value = avgLum
262246
}
263-
},
247+
}
264248

265-
setMiddleGrey: function (middleGrey) {
249+
setMiddleGrey(middleGrey) {
266250
if (middleGrey) {
267251
this.materialToneMap.uniforms.middleGrey.value = middleGrey
268252
}
269-
},
253+
}
270254

271-
dispose: function () {
255+
dispose() {
272256
if (this.luminanceRT) {
273257
this.luminanceRT.dispose()
274258
}
@@ -296,7 +280,7 @@ AdaptiveToneMappingPass.prototype = Object.assign(Object.create(Pass.prototype),
296280
if (this.materialToneMap) {
297281
this.materialToneMap.dispose()
298282
}
299-
},
300-
})
283+
}
284+
}
301285

302286
export { AdaptiveToneMappingPass }

0 commit comments

Comments
 (0)