Skip to content

Commit 88f2493

Browse files
authored
Merge pull request #15299 from jsantell/update-background-texture
Recompile WebGLBackground's material when the background changes
2 parents e7b71af + 17029e1 commit 88f2493

File tree

3 files changed

+103
-41
lines changed

3 files changed

+103
-41
lines changed

examples/webgl_materials_envmaps_exr.html

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,13 @@
5656
envMap: 'EXR',
5757
roughness: 0.0,
5858
metalness: 0.0,
59-
exposure: 1.0
59+
exposure: 1.0,
60+
showBackground: true,
6061
};
6162
var camera, scene, renderer, controls, objects = [];
6263
var standardMaterial, floorMaterial;
6364
var pngCubeRenderTarget, exrCubeRenderTarget;
65+
var pngBackground, exrBackground;
6466

6567
init();
6668
animate();
@@ -111,6 +113,7 @@
111113
texture.encoding = THREE.LinearEncoding;
112114

113115
var cubemapGenerator = new THREE.EquirectangularToCubeGenerator( texture, { resolution: 512, type: THREE.HalfFloatType } );
116+
exrBackground = cubemapGenerator.renderTarget;
114117
var cubeMapTexture = cubemapGenerator.update( renderer );
115118

116119
var pmremGenerator = new THREE.PMREMGenerator( cubeMapTexture );
@@ -122,7 +125,6 @@
122125
exrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
123126

124127
texture.dispose();
125-
cubemapGenerator.dispose();
126128
pmremGenerator.dispose();
127129
pmremCubeUVPacker.dispose();
128130

@@ -133,6 +135,8 @@
133135
texture.encoding = THREE.sRGBEncoding;
134136

135137
var cubemapGenerator = new THREE.EquirectangularToCubeGenerator( texture, { resolution: 512 } );
138+
pngBackground = cubemapGenerator.renderTarget;
139+
136140
var cubeMapTexture = cubemapGenerator.update( renderer );
137141

138142
var pmremGenerator = new THREE.PMREMGenerator( cubeMapTexture );
@@ -144,7 +148,6 @@
144148
pngCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
145149

146150
texture.dispose();
147-
cubemapGenerator.dispose();
148151
pmremGenerator.dispose();
149152
pmremCubeUVPacker.dispose();
150153

@@ -173,6 +176,7 @@
173176
gui.add( params, 'roughness', 0, 1 );
174177
gui.add( params, 'metalness', 0, 1 );
175178
gui.add( params, 'exposure', 0, 2 );
179+
gui.add( params, 'showBackground', true);
176180
gui.open();
177181

178182
}
@@ -201,32 +205,45 @@
201205

202206
function render() {
203207

204-
if ( standardMaterial !== undefined ) {
208+
standardMaterial.roughness = params.roughness;
209+
standardMaterial.metalness = params.metalness;
210+
211+
var newEnvMap = standardMaterial.envMap;
205212

206-
standardMaterial.roughness = params.roughness;
207-
standardMaterial.metalness = params.metalness;
213+
switch ( params.envMap ) {
208214

209-
var newEnvMap = standardMaterial.envMap;
215+
case 'EXR':
216+
newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null;
217+
background = exrBackground;
218+
break;
219+
case 'PNG':
220+
newEnvMap = pngCubeRenderTarget ? pngCubeRenderTarget.texture : null;
221+
background = pngBackground;
222+
break;
210223

211-
switch ( params.envMap ) {
224+
}
212225

213-
case 'EXR': newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null; break;
214-
case 'PNG': newEnvMap = pngCubeRenderTarget ? pngCubeRenderTarget.texture : null; break;
226+
if ( newEnvMap !== standardMaterial.envMap ) {
215227

216-
}
228+
standardMaterial.envMap = newEnvMap;
229+
standardMaterial.needsUpdate = true;
217230

218-
if ( newEnvMap !== standardMaterial.envMap ) {
231+
floorMaterial.map = newEnvMap;
232+
floorMaterial.needsUpdate = true;
219233

220-
standardMaterial.envMap = newEnvMap;
221-
standardMaterial.needsUpdate = true;
234+
}
222235

223-
floorMaterial.map = newEnvMap;
224-
floorMaterial.needsUpdate = true;
236+
if ( ! params.showBackground ) {
225237

226-
}
238+
scene.background = null;
239+
240+
} else {
241+
242+
scene.background = background;
227243

228244
}
229245

246+
230247
renderer.toneMappingExposure = params.exposure;
231248

232249
for ( var i = 0, l = objects.length; i < l; i ++ ) {

examples/webgl_materials_envmaps_hdr.html

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,13 @@
5757
envMap: 'HDR',
5858
roughness: 0.0,
5959
metalness: 0.0,
60-
exposure: 1.0
60+
exposure: 1.0,
61+
showBackground: true
6162
};
6263
var camera, scene, renderer, controls, objects = [];
6364
var standardMaterial, floorMaterial;
6465
var ldrCubeRenderTarget, hdrCubeRenderTarget, rgbmCubeRenderTarget;
66+
var ldrCubeMap, hdrCubeMap, rgbmCubeMap;
6567

6668
init();
6769
animate();
@@ -114,7 +116,7 @@
114116
};
115117

116118
var hdrUrls = genCubeUrls( './textures/cube/pisaHDR/', '.hdr' );
117-
new THREE.HDRCubeTextureLoader().load( THREE.UnsignedByteType, hdrUrls, function ( hdrCubeMap ) {
119+
hdrCubeMap = new THREE.HDRCubeTextureLoader().load( THREE.UnsignedByteType, hdrUrls, function () {
118120

119121
var pmremGenerator = new THREE.PMREMGenerator( hdrCubeMap );
120122
pmremGenerator.update( renderer );
@@ -124,14 +126,13 @@
124126

125127
hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
126128

127-
hdrCubeMap.dispose();
128129
pmremGenerator.dispose();
129130
pmremCubeUVPacker.dispose();
130131

131132
} );
132133

133134
var ldrUrls = genCubeUrls( './textures/cube/pisa/', '.png' );
134-
new THREE.CubeTextureLoader().load( ldrUrls, function ( ldrCubeMap ) {
135+
ldrCubeMap = new THREE.CubeTextureLoader().load( ldrUrls, function () {
135136

136137
ldrCubeMap.encoding = THREE.GammaEncoding;
137138

@@ -143,15 +144,14 @@
143144

144145
ldrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
145146

146-
ldrCubeMap.dispose();
147147
pmremGenerator.dispose();
148148
pmremCubeUVPacker.dispose();
149149

150150
} );
151151

152152

153153
var rgbmUrls = genCubeUrls( './textures/cube/pisaRGBM16/', '.png' );
154-
new THREE.CubeTextureLoader().load( rgbmUrls, function ( rgbmCubeMap ) {
154+
rgbmCubeMap = new THREE.CubeTextureLoader().load( rgbmUrls, function () {
155155

156156
rgbmCubeMap.encoding = THREE.RGBM16Encoding;
157157

@@ -163,7 +163,6 @@
163163

164164
rgbmCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
165165

166-
rgbmCubeMap.dispose();
167166
pmremGenerator.dispose();
168167
pmremCubeUVPacker.dispose();
169168

@@ -192,6 +191,7 @@
192191
gui.add( params, 'roughness', 0, 1 );
193192
gui.add( params, 'metalness', 0, 1 );
194193
gui.add( params, 'exposure', 0, 2 );
194+
gui.add( params, 'showBackground', true );
195195
gui.open();
196196

197197
}
@@ -220,30 +220,45 @@
220220

221221
function render() {
222222

223-
if ( standardMaterial !== undefined ) {
224-
225-
standardMaterial.roughness = params.roughness;
226-
standardMaterial.metalness = params.metalness;
223+
standardMaterial.roughness = params.roughness;
224+
standardMaterial.metalness = params.metalness;
225+
226+
var renderTarget, cubeMap;
227+
228+
switch ( params.envMap ) {
229+
230+
case 'LDR':
231+
renderTarget = ldrCubeRenderTarget;
232+
cubeMap = ldrCubeMap;
233+
break;
234+
case 'HDR':
235+
renderTarget = hdrCubeRenderTarget;
236+
cubeMap = hdrCubeMap;
237+
break;
238+
case 'RGBM16':
239+
renderTarget = rgbmCubeRenderTarget;
240+
cubeMap = rgbmCubeMap;
241+
break;
242+
}
227243

228-
var newEnvMap = standardMaterial.envMap;
244+
var newEnvMap = renderTarget ? renderTarget.texture : null;
229245

230-
switch ( params.envMap ) {
246+
if ( newEnvMap && newEnvMap !== standardMaterial.envMap ) {
231247

232-
case 'LDR': newEnvMap = ldrCubeRenderTarget ? ldrCubeRenderTarget.texture : null; break;
233-
case 'HDR': newEnvMap = hdrCubeRenderTarget ? hdrCubeRenderTarget.texture : null; break;
234-
case 'RGBM16': newEnvMap = rgbmCubeRenderTarget ? rgbmCubeRenderTarget.texture : null; break;
248+
standardMaterial.envMap = newEnvMap;
249+
standardMaterial.needsUpdate = true;
235250

236-
}
251+
floorMaterial.map = newEnvMap;
252+
floorMaterial.needsUpdate = true;
253+
}
237254

238-
if ( newEnvMap !== standardMaterial.envMap ) {
255+
if ( ! params.showBackground ) {
239256

240-
standardMaterial.envMap = newEnvMap;
241-
standardMaterial.needsUpdate = true;
257+
scene.background = null;
242258

243-
floorMaterial.map = newEnvMap;
244-
floorMaterial.needsUpdate = true;
259+
} else {
245260

246-
}
261+
scene.background = cubeMap;
247262

248263
}
249264

src/renderers/webgl/WebGLBackground.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
1818

1919
var planeMesh;
2020
var boxMesh;
21+
// Store the current background texture and its `version`
22+
// so we can recompile the material accordingly.
23+
var currentBackground = null;
24+
var currentBackgroundVersion = 0;
2125

2226
function render( renderList, scene, camera, forceClear ) {
2327

@@ -26,11 +30,15 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
2630
if ( background === null ) {
2731

2832
setClear( clearColor, clearAlpha );
33+
currentBackground = null;
34+
currentBackgroundVersion = 0;
2935

3036
} else if ( background && background.isColor ) {
3137

3238
setClear( background, 1 );
3339
forceClear = true;
40+
currentBackground = null;
41+
currentBackgroundVersion = 0;
3442

3543
}
3644

@@ -82,9 +90,20 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
8290

8391
}
8492

85-
boxMesh.material.uniforms.tCube.value = ( background.isWebGLRenderTargetCube ) ? background.texture : background;
93+
var texture = background.isWebGLRenderTargetCube ? background.texture : background;
94+
boxMesh.material.uniforms.tCube.value = texture;
8695
boxMesh.material.uniforms.tFlip.value = ( background.isWebGLRenderTargetCube ) ? 1 : - 1;
8796

97+
if ( currentBackground !== background ||
98+
currentBackgroundVersion !== texture.version ) {
99+
100+
boxMesh.material.needsUpdate = true;
101+
102+
currentBackground = background;
103+
currentBackgroundVersion = texture.version;
104+
105+
}
106+
88107
// push to the pre-sorted opaque render list
89108
renderList.push( boxMesh, boxMesh.geometry, boxMesh.material, 0, null );
90109

@@ -133,6 +152,17 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
133152

134153
planeMesh.material.uniforms.uvTransform.value.copy( background.matrix );
135154

155+
if ( currentBackground !== background ||
156+
currentBackgroundVersion !== background.version ) {
157+
158+
planeMesh.material.needsUpdate = true;
159+
160+
currentBackground = background;
161+
currentBackgroundVersion = background.version;
162+
163+
}
164+
165+
136166
// push to the pre-sorted opaque render list
137167
renderList.push( planeMesh, planeMesh.geometry, planeMesh.material, 0, null );
138168

0 commit comments

Comments
 (0)