Explorar el Código

Recompile WebGLBackground's material when the background changes to accomodate new encodings, formats, etc. Fixes #15325

Jordan Santell hace 6 años
padre
commit
17029e17b5

+ 34 - 17
examples/webgl_materials_envmaps_exr.html

@@ -56,11 +56,13 @@
 				envMap: 'EXR',
 				roughness: 0.0,
 				metalness: 0.0,
-				exposure: 1.0
+				exposure: 1.0,
+				showBackground: true,
 			};
 			var camera, scene, renderer, controls, objects = [];
 			var standardMaterial, floorMaterial;
 			var pngCubeRenderTarget, exrCubeRenderTarget;
+			var pngBackground, exrBackground;
 
 			init();
 			animate();
@@ -111,6 +113,7 @@
 					texture.encoding = THREE.LinearEncoding;
 
 					var cubemapGenerator = new THREE.EquirectangularToCubeGenerator( texture, { resolution: 512, type: THREE.HalfFloatType } );
+					exrBackground = cubemapGenerator.renderTarget;
 					var cubeMapTexture = cubemapGenerator.update( renderer );
 
 					var pmremGenerator = new THREE.PMREMGenerator( cubeMapTexture );
@@ -122,7 +125,6 @@
 					exrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
 
 					texture.dispose();
-					cubemapGenerator.dispose();
 					pmremGenerator.dispose();
 					pmremCubeUVPacker.dispose();
 
@@ -133,6 +135,8 @@
 					texture.encoding = THREE.sRGBEncoding;
 
 					var cubemapGenerator = new THREE.EquirectangularToCubeGenerator( texture, { resolution: 512 } );
+					pngBackground = cubemapGenerator.renderTarget;
+
 					var cubeMapTexture = cubemapGenerator.update( renderer );
 
 					var pmremGenerator = new THREE.PMREMGenerator( cubeMapTexture );
@@ -144,7 +148,6 @@
 					pngCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
 
 					texture.dispose();
-					cubemapGenerator.dispose();
 					pmremGenerator.dispose();
 					pmremCubeUVPacker.dispose();
 
@@ -173,6 +176,7 @@
 				gui.add( params, 'roughness', 0, 1 );
 				gui.add( params, 'metalness', 0, 1 );
 				gui.add( params, 'exposure', 0, 2 );
+				gui.add( params, 'showBackground', true);
 				gui.open();
 
 			}
@@ -201,32 +205,45 @@
 
 			function render() {
 
-				if ( standardMaterial !== undefined ) {
+				standardMaterial.roughness = params.roughness;
+				standardMaterial.metalness = params.metalness;
+
+				var newEnvMap = standardMaterial.envMap;
 
-					standardMaterial.roughness = params.roughness;
-					standardMaterial.metalness = params.metalness;
+				switch ( params.envMap ) {
 
-					var newEnvMap = standardMaterial.envMap;
+					case 'EXR':
+						newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null;
+						background = exrBackground;
+						break;
+					case 'PNG':
+						newEnvMap = pngCubeRenderTarget ? pngCubeRenderTarget.texture : null;
+						background = pngBackground;
+						break;
 
-					switch ( params.envMap ) {
+				}
 
-						case 'EXR': newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null; break;
-						case 'PNG': newEnvMap = pngCubeRenderTarget ? pngCubeRenderTarget.texture : null; break;
+				if ( newEnvMap !== standardMaterial.envMap ) {
 
-					}
+					standardMaterial.envMap = newEnvMap;
+					standardMaterial.needsUpdate = true;
 
-					if ( newEnvMap !== standardMaterial.envMap ) {
+					floorMaterial.map = newEnvMap;
+					floorMaterial.needsUpdate = true;
 
-						standardMaterial.envMap = newEnvMap;
-						standardMaterial.needsUpdate = true;
+				}
 
-						floorMaterial.map = newEnvMap;
-						floorMaterial.needsUpdate = true;
+				if ( ! params.showBackground ) {
 
-					}
+					scene.background = null;
+
+				} else {
+
+					scene.background = background;
 
 				}
 
+
 				renderer.toneMappingExposure = params.exposure;
 
 				for ( var i = 0, l = objects.length; i < l; i ++ ) {

+ 38 - 23
examples/webgl_materials_envmaps_hdr.html

@@ -57,11 +57,13 @@
 				envMap: 'HDR',
 				roughness: 0.0,
 				metalness: 0.0,
-				exposure: 1.0
+				exposure: 1.0,
+				showBackground: true
 			};
 			var camera, scene, renderer, controls, objects = [];
 			var standardMaterial, floorMaterial;
 			var ldrCubeRenderTarget, hdrCubeRenderTarget, rgbmCubeRenderTarget;
+			var ldrCubeMap, hdrCubeMap, rgbmCubeMap;
 
 			init();
 			animate();
@@ -114,7 +116,7 @@
 				};
 
 				var hdrUrls = genCubeUrls( './textures/cube/pisaHDR/', '.hdr' );
-				new THREE.HDRCubeTextureLoader().load( THREE.UnsignedByteType, hdrUrls, function ( hdrCubeMap ) {
+				hdrCubeMap = new THREE.HDRCubeTextureLoader().load( THREE.UnsignedByteType, hdrUrls, function () {
 
 					var pmremGenerator = new THREE.PMREMGenerator( hdrCubeMap );
 					pmremGenerator.update( renderer );
@@ -124,14 +126,13 @@
 
 					hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
 
-					hdrCubeMap.dispose();
 					pmremGenerator.dispose();
 					pmremCubeUVPacker.dispose();
 
 				} );
 
 				var ldrUrls = genCubeUrls( './textures/cube/pisa/', '.png' );
-				new THREE.CubeTextureLoader().load( ldrUrls, function ( ldrCubeMap ) {
+				ldrCubeMap = new THREE.CubeTextureLoader().load( ldrUrls, function () {
 
 					ldrCubeMap.encoding = THREE.GammaEncoding;
 
@@ -143,7 +144,6 @@
 
 					ldrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
 
-					ldrCubeMap.dispose();
 					pmremGenerator.dispose();
 					pmremCubeUVPacker.dispose();
 
@@ -151,7 +151,7 @@
 
 
 				var rgbmUrls = genCubeUrls( './textures/cube/pisaRGBM16/', '.png' );
-				new THREE.CubeTextureLoader().load( rgbmUrls, function ( rgbmCubeMap ) {
+				rgbmCubeMap = new THREE.CubeTextureLoader().load( rgbmUrls, function () {
 
 					rgbmCubeMap.encoding = THREE.RGBM16Encoding;
 
@@ -163,7 +163,6 @@
 
 					rgbmCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
 
-					rgbmCubeMap.dispose();
 					pmremGenerator.dispose();
 					pmremCubeUVPacker.dispose();
 
@@ -192,6 +191,7 @@
 				gui.add( params, 'roughness', 0, 1 );
 				gui.add( params, 'metalness', 0, 1 );
 				gui.add( params, 'exposure', 0, 2 );
+				gui.add( params, 'showBackground', true );
 				gui.open();
 
 			}
@@ -220,30 +220,45 @@
 
 			function render() {
 
-				if ( standardMaterial !== undefined ) {
-
-					standardMaterial.roughness = params.roughness;
-					standardMaterial.metalness = params.metalness;
+				standardMaterial.roughness = params.roughness;
+				standardMaterial.metalness = params.metalness;
+
+				var renderTarget, cubeMap;
+
+				switch ( params.envMap ) {
+
+					case 'LDR':
+						renderTarget = ldrCubeRenderTarget;
+						cubeMap = ldrCubeMap;
+						break;
+					case 'HDR':
+						renderTarget = hdrCubeRenderTarget;
+						cubeMap = hdrCubeMap;
+						break;
+					case 'RGBM16':
+						renderTarget = rgbmCubeRenderTarget;
+						cubeMap = rgbmCubeMap;
+						break;
+				}
 
-					var newEnvMap = standardMaterial.envMap;
+				var newEnvMap = renderTarget ? renderTarget.texture : null;
 
-					switch ( params.envMap ) {
+				if ( newEnvMap && newEnvMap !== standardMaterial.envMap ) {
 
-						case 'LDR': newEnvMap = ldrCubeRenderTarget ? ldrCubeRenderTarget.texture : null; break;
-						case 'HDR': newEnvMap = hdrCubeRenderTarget ? hdrCubeRenderTarget.texture : null; break;
-						case 'RGBM16': newEnvMap = rgbmCubeRenderTarget ? rgbmCubeRenderTarget.texture : null; break;
+					standardMaterial.envMap = newEnvMap;
+					standardMaterial.needsUpdate = true;
 
-					}
+					floorMaterial.map = newEnvMap;
+					floorMaterial.needsUpdate = true;
+				}
 
-					if ( newEnvMap !== standardMaterial.envMap ) {
+				if ( ! params.showBackground ) {
 
-						standardMaterial.envMap = newEnvMap;
-						standardMaterial.needsUpdate = true;
+					scene.background = null;
 
-						floorMaterial.map = newEnvMap;
-						floorMaterial.needsUpdate = true;
+				} else {
 
-					}
+					scene.background = cubeMap;
 
 				}
 

+ 31 - 1
src/renderers/webgl/WebGLBackground.js

@@ -18,6 +18,10 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
 
 	var planeMesh;
 	var boxMesh;
+	// Store the current background texture and its `version`
+	// so we can recompile the material accordingly.
+	var currentBackground = null;
+	var currentBackgroundVersion = 0;
 
 	function render( renderList, scene, camera, forceClear ) {
 
@@ -26,11 +30,15 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
 		if ( background === null ) {
 
 			setClear( clearColor, clearAlpha );
+			currentBackground = null;
+			currentBackgroundVersion = 0;
 
 		} else if ( background && background.isColor ) {
 
 			setClear( background, 1 );
 			forceClear = true;
+			currentBackground = null;
+			currentBackgroundVersion = 0;
 
 		}
 
@@ -82,9 +90,20 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
 
 			}
 
-			boxMesh.material.uniforms.tCube.value = ( background.isWebGLRenderTargetCube ) ? background.texture : background;
+			var texture = background.isWebGLRenderTargetCube ? background.texture : background;
+			boxMesh.material.uniforms.tCube.value = texture;
 			boxMesh.material.uniforms.tFlip.value = ( background.isWebGLRenderTargetCube ) ? 1 : - 1;
 
+			if ( currentBackground !== background ||
+			     currentBackgroundVersion !== texture.version ) {
+
+				boxMesh.material.needsUpdate = true;
+
+				currentBackground = background;
+				currentBackgroundVersion = texture.version;
+
+			}
+
 			// push to the pre-sorted opaque render list
 			renderList.push( boxMesh, boxMesh.geometry, boxMesh.material, 0, null );
 
@@ -133,6 +152,17 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
 
 			planeMesh.material.uniforms.uvTransform.value.copy( background.matrix );
 
+			if ( currentBackground !== background ||
+				   currentBackgroundVersion !== background.version ) {
+
+				planeMesh.material.needsUpdate = true;
+
+				currentBackground = background;
+				currentBackgroundVersion = background.version;
+
+			}
+
+
 			// push to the pre-sorted opaque render list
 			renderList.push( planeMesh, planeMesh.geometry, planeMesh.material, 0, null );