소스 검색

Merge pull request #18196 from elalish/compilePMREM

Pre-compile PMREM
Mr.doob 5 년 전
부모
커밋
3f7ce0eeb9

+ 39 - 0
examples/js/pmrem/PMREMGenerator.js

@@ -65,6 +65,7 @@ THREE.PMREMGenerator = ( function () {
 	var PMREMGenerator = function ( renderer ) {
 
 		_renderer = renderer;
+		_compileMaterial( _blurMaterial );
 
 	};
 
@@ -128,6 +129,36 @@ THREE.PMREMGenerator = ( function () {
 
 		},
 
+		/**
+		 * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during
+		 * your texture's network fetch for increased concurrency.
+		 */
+		compileCubemapShader: function () {
+
+			if ( _cubemapShader == null ) {
+
+				_cubemapShader = _getCubemapShader();
+				_compileMaterial( _cubemapShader );
+
+			}
+
+		},
+
+		/**
+		 * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during
+		 * your texture's network fetch for increased concurrency.
+		 */
+		compileEquirectangularShader: function () {
+
+			if ( _equirectShader == null ) {
+
+				_equirectShader = _getEquirectShader();
+				_compileMaterial( _equirectShader );
+
+			}
+
+		},
+
 		/**
 		 * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class,
 		 * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on
@@ -359,6 +390,14 @@ THREE.PMREMGenerator = ( function () {
 
 	}
 
+	function _compileMaterial( material ) {
+
+		var tmpScene = new THREE.Scene();
+		tmpScene.add( new THREE.Mesh( _lodPlanes[ 0 ], material ) );
+		_renderer.compile( tmpScene, _flatCamera );
+
+	}
+
 	function _createRenderTarget( params ) {
 
 		var cubeUVRenderTarget =

+ 2 - 0
examples/jsm/pmrem/PMREMGenerator.d.ts

@@ -12,6 +12,8 @@ export class PMREMGenerator {
 	fromScene( scene:Scene, sigma?:number, near?:number, far?:number ): WebGLRenderTarget;
 	fromEquirectangular( equirectangular:Texture ): WebGLRenderTarget;
 	fromCubemap( cubemap:CubeTexture ): WebGLRenderTarget;
+	compileCubemapShader(): void;
+	compileEquirectangularShader(): void;
 	dispose(): void;
 
 }

+ 39 - 0
examples/jsm/pmrem/PMREMGenerator.js

@@ -91,6 +91,7 @@ var PMREMGenerator = ( function () {
 	var PMREMGenerator = function ( renderer ) {
 
 		_renderer = renderer;
+		_compileMaterial( _blurMaterial );
 
 	};
 
@@ -154,6 +155,36 @@ var PMREMGenerator = ( function () {
 
 		},
 
+		/**
+		 * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during
+		 * your texture's network fetch for increased concurrency.
+		 */
+		compileCubemapShader: function () {
+
+			if ( _cubemapShader == null ) {
+
+				_cubemapShader = _getCubemapShader();
+				_compileMaterial( _cubemapShader );
+
+			}
+
+		},
+
+		/**
+		 * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during
+		 * your texture's network fetch for increased concurrency.
+		 */
+		compileEquirectangularShader: function () {
+
+			if ( _equirectShader == null ) {
+
+				_equirectShader = _getEquirectShader();
+				_compileMaterial( _equirectShader );
+
+			}
+
+		},
+
 		/**
 		 * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class,
 		 * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on
@@ -385,6 +416,14 @@ var PMREMGenerator = ( function () {
 
 	}
 
+	function _compileMaterial( material ) {
+
+		var tmpScene = new Scene();
+		tmpScene.add( new Mesh( _lodPlanes[ 0 ], material ) );
+		_renderer.compile( tmpScene, _flatCamera );
+
+	}
+
 	function _createRenderTarget( params ) {
 
 		var cubeUVRenderTarget =

+ 3 - 1
examples/webgl_loader_gltf.html

@@ -48,7 +48,6 @@
 					.setPath( 'textures/equirectangular/' )
 					.load( 'pedestrian_overpass_1k.hdr', function ( texture ) {
 
-						var pmremGenerator = new PMREMGenerator( renderer );
 						var envMap = pmremGenerator.fromEquirectangular( texture ).texture;
 						pmremGenerator.dispose();
 
@@ -86,6 +85,9 @@
 				renderer.outputEncoding = THREE.sRGBEncoding;
 				container.appendChild( renderer.domElement );
 
+				var pmremGenerator = new PMREMGenerator( renderer );
+				pmremGenerator.compileEquirectangularShader();
+
 				controls = new OrbitControls( camera, renderer.domElement );
 				controls.target.set( 0, - 0.2, - 0.2 );
 				controls.update();

+ 3 - 1
examples/webgl_loader_gltf_extensions.html

@@ -157,7 +157,6 @@
 					.setPath( 'textures/equirectangular/' )
 					.load( 'venice_sunset_1k.hdr', function ( texture ) {
 
-						var pmremGenerator = new PMREMGenerator( renderer );
 						envMap = pmremGenerator.fromEquirectangular( texture ).texture;
 						pmremGenerator.dispose();
 
@@ -171,6 +170,9 @@
 
 					} );
 
+				var pmremGenerator = new PMREMGenerator( renderer );
+				pmremGenerator.compileEquirectangularShader();
+
 			}
 
 			function initScene( sceneInfo ) {

+ 3 - 1
examples/webgl_materials_car.html

@@ -69,7 +69,6 @@
 					.setPath( 'textures/hdr/' )
 					.load( 'quarry_01_1k.hdr', function ( texture ) {
 
-						var pmremGenerator = new PMREMGenerator( renderer );
 						envMap = pmremGenerator.fromEquirectangular( texture ).texture;
 						pmremGenerator.dispose();
 
@@ -105,6 +104,9 @@
 				renderer.outputEncoding = THREE.sRGBEncoding;
 				renderer.toneMapping = THREE.ACESFilmicToneMapping;
 
+				var pmremGenerator = new PMREMGenerator( renderer );
+				pmremGenerator.compileEquirectangularShader();
+
 				stats = new Stats();
 				container.appendChild( stats.dom );
 

+ 3 - 1
examples/webgl_materials_envmaps_exr.html

@@ -72,7 +72,6 @@
 				planeMesh.rotation.x = - Math.PI * 0.5;
 				scene.add( planeMesh );
 
-				var pmremGenerator = new PMREMGenerator( renderer );
 				THREE.DefaultLoadingManager.onLoad = function ( ) {
 
 					pmremGenerator.dispose();
@@ -102,6 +101,9 @@
 
 				} );
 
+				var pmremGenerator = new PMREMGenerator( renderer );
+				pmremGenerator.compileEquirectangularShader();
+
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 

+ 6 - 4
examples/webgl_materials_envmaps_hdr.html

@@ -113,16 +113,12 @@
 				planeMesh.rotation.x = - Math.PI * 0.5;
 				scene.add( planeMesh );
 
-				var pmremGenerator = new PMREMGenerator( renderer );
 				THREE.DefaultLoadingManager.onLoad = function ( ) {
 
 					pmremGenerator.dispose();
 
 				};
 
-				var envScene = getEnvScene();
-				generatedCubeRenderTarget = pmremGenerator.fromScene( envScene, 0.04 );
-
 				var hdrUrls = [ 'px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr' ];
 				hdrCubeMap = new HDRCubeTextureLoader()
 					.setPath( './textures/cube/pisaHDR/' )
@@ -163,6 +159,12 @@
 
 					} );
 
+				var pmremGenerator = new PMREMGenerator( renderer );
+				pmremGenerator.compileCubemapShader();
+
+				var envScene = getEnvScene();
+				generatedCubeRenderTarget = pmremGenerator.fromScene( envScene, 0.04 );
+
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				container.appendChild( renderer.domElement );

+ 6 - 4
examples/webgl_materials_envmaps_hdr_nodes.html

@@ -125,16 +125,12 @@
 				planeMesh.rotation.x = - Math.PI * 0.5;
 				scene.add( planeMesh );
 
-				var pmremGenerator = new PMREMGenerator( renderer );
 				THREE.DefaultLoadingManager.onLoad = function ( ) {
 
 					pmremGenerator.dispose();
 
 				};
 
-				var envScene = getEnvScene();
-				generatedCubeRenderTarget = pmremGenerator.fromScene( envScene, 0.04 );
-
 				var hdrUrls = [ 'px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr' ];
 				hdrCubeMap = new HDRCubeTextureLoader()
 					.setPath( './textures/cube/pisaHDR/' )
@@ -175,6 +171,12 @@
 
 					} );
 
+				var pmremGenerator = new PMREMGenerator( renderer );
+				pmremGenerator.compileCubemapShader();
+
+				var envScene = getEnvScene();
+				generatedCubeRenderTarget = pmremGenerator.fromScene( envScene, 0.04 );
+
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				container.appendChild( renderer.domElement );

+ 13 - 17
examples/webgl_materials_envmaps_pmrem_nodes.html

@@ -68,22 +68,6 @@
 			init();
 			animate();
 
-			function generate() {
-
-				var pmremGenerator = new PMREMGenerator( renderer );
-				hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap );
-				pmremGenerator.dispose();
-
-				nodeTexture.value = hdrCubeRenderTarget.texture;
-
-				hdrCubeMap.magFilter = THREE.LinearFilter;
-				hdrCubeMap.needsUpdate = true;
-
-				planeMesh.material.map = hdrCubeRenderTarget.texture;
-				planeMesh.material.needsUpdate = true;
-
-			}
-
 			function init() {
 
 				container = document.createElement( 'div' );
@@ -127,12 +111,24 @@
 					.setDataType( THREE.UnsignedByteType )
 					.load( hdrUrls, function () {
 
-						generate();
+						hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap );
+						pmremGenerator.dispose();
+
+						nodeTexture.value = hdrCubeRenderTarget.texture;
+
+						hdrCubeMap.magFilter = THREE.LinearFilter;
+						hdrCubeMap.needsUpdate = true;
+
+						planeMesh.material.map = hdrCubeRenderTarget.texture;
+						planeMesh.material.needsUpdate = true;
 
 						nodeMaterial.visible = true;
 
 					} );
 
+				var pmremGenerator = new PMREMGenerator( renderer );
+				pmremGenerator.compileCubemapShader();
+
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				container.appendChild( renderer.domElement );

+ 8 - 4
examples/webgl_materials_physical_clearcoat.html

@@ -49,11 +49,10 @@
 			new RGBELoader()
 					.setDataType( THREE.UnsignedByteType )
 					.setPath( 'textures/equirectangular/' )
-					.load( 'pedestrian_overpass_1k.hdr', function ( hdrCubeMap ) {
+					.load( 'pedestrian_overpass_1k.hdr', function ( hdrEquirect ) {
 
-						var pmremGenerator = new PMREMGenerator( renderer );
-						var hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap );
-						hdrCubeMap.dispose();
+						var hdrCubeRenderTarget = pmremGenerator.fromEquirectangular( hdrEquirect );
+						hdrEquirect.dispose();
 						pmremGenerator.dispose();
 
 						var geometry = new THREE.SphereBufferGeometry( 80, 64, 32 );
@@ -183,6 +182,11 @@
 
 			//
 
+			var pmremGenerator = new PMREMGenerator( renderer );
+			pmremGenerator.compileEquirectangularShader();
+
+			//
+
 			stats = new Stats();
 			container.appendChild( stats.dom );
 

+ 4 - 4
examples/webgl_materials_physical_transparency.html

@@ -37,7 +37,7 @@
 			var spotLight1, spotLight2;
 			var mesh1, mesh2;
 
-			var hdrCubeMap = new RGBELoader()
+			var hdrEquirect = new RGBELoader()
 				.setDataType( THREE.UnsignedByteType )
 				.setPath( 'textures/equirectangular/' )
 				.load( 'pedestrian_overpass_1k.hdr', function ( texture ) {
@@ -64,7 +64,7 @@
 				renderer.outputEncoding = THREE.sRGBEncoding;
 
 				scene = new THREE.Scene();
-				scene.background = hdrCubeMap;
+				scene.background = hdrEquirect;
 
 				camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 2000 );
 				camera.position.set( 0, 0, 120 );
@@ -72,8 +72,8 @@
 				//
 
 				var pmremGenerator = new PMREMGenerator( renderer );
-				hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap );
-				hdrCubeMap.dispose();
+				hdrCubeRenderTarget = pmremGenerator.fromEquirectangular( hdrEquirect );
+				hdrEquirect.dispose();
 				pmremGenerator.dispose();
 
 				scene.background = hdrCubeRenderTarget.texture;

+ 5 - 4
examples/webgl_materials_reflectivity.html

@@ -115,19 +115,20 @@
 				new RGBELoader()
 					.setDataType( THREE.UnsignedByteType )
 					.setPath( 'textures/equirectangular/' )
-					.load( 'pedestrian_overpass_1k.hdr', function ( hdrCubeMap ) {
+					.load( 'pedestrian_overpass_1k.hdr', function ( hdrEquirect ) {
 
-						var pmremGenerator = new PMREMGenerator( renderer );
-						hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap );
+						hdrCubeRenderTarget = pmremGenerator.fromEquirectangular( hdrEquirect );
 						pmremGenerator.dispose();
 
 						gemFrontMaterial.envMap = gemBackMaterial.envMap = hdrCubeRenderTarget.texture;
 						gemFrontMaterial.needsUpdate = gemBackMaterial.needsUpdate = true;
 
-						hdrCubeMap.dispose();
+						hdrEquirect.dispose();
 
 					} );
 
+				var pmremGenerator = new PMREMGenerator( renderer );
+				pmremGenerator.compileEquirectangularShader();
 
 				// Lights
 

+ 6 - 4
examples/webgl_materials_standard.html

@@ -105,11 +105,10 @@
 				new RGBELoader()
 					.setDataType( THREE.UnsignedByteType )
 					.setPath( 'textures/equirectangular/' )
-					.load( 'venice_sunset_1k.hdr', function ( hdrCubeMap ) {
+					.load( 'venice_sunset_1k.hdr', function ( hdrEquirect ) {
 
-						var pmremGenerator = new PMREMGenerator( renderer );
-						var hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap );
-						hdrCubeMap.dispose();
+						var hdrCubeRenderTarget = pmremGenerator.fromEquirectangular( hdrEquirect );
+						hdrEquirect.dispose();
 						pmremGenerator.dispose();
 
 						material.envMap = hdrCubeRenderTarget.texture;
@@ -118,6 +117,9 @@
 
 					} );
 
+				var pmremGenerator = new PMREMGenerator( renderer );
+				pmremGenerator.compileEquirectangularShader();
+
 				//
 
 				if ( statsEnabled ) {

+ 8 - 4
examples/webgl_materials_variations_physical.html

@@ -52,11 +52,10 @@
 				new RGBELoader()
 					.setDataType( THREE.UnsignedByteType )
 					.setPath( 'textures/equirectangular/' )
-					.load( 'pedestrian_overpass_1k.hdr', function ( hdrCubeMap ) {
+					.load( 'pedestrian_overpass_1k.hdr', function ( hdrEquirect ) {
 
-						var pmremGenerator = new PMREMGenerator( renderer );
-						hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap );
-						hdrCubeMap.dispose();
+						hdrCubeRenderTarget = pmremGenerator.fromEquirectangular( hdrEquirect );
+						hdrEquirect.dispose();
 						pmremGenerator.dispose();
 
 						// Materials
@@ -165,6 +164,11 @@
 
 				//
 
+				var pmremGenerator = new PMREMGenerator( renderer );
+				pmremGenerator.compileEquirectangularShader();
+
+				//
+
 				stats = new Stats();
 				container.appendChild( stats.dom );
 

+ 8 - 4
examples/webgl_materials_variations_standard.html

@@ -57,11 +57,10 @@
 				new RGBELoader()
 					.setDataType( THREE.UnsignedByteType )
 					.setPath( 'textures/equirectangular/' )
-					.load( 'pedestrian_overpass_1k.hdr', function ( hdrCubeMap ) {
+					.load( 'pedestrian_overpass_1k.hdr', function ( hdrEquirect ) {
 
-						var pmremGenerator = new PMREMGenerator( renderer );
-						hdrCubeRenderTarget = pmremGenerator.fromCubemap( hdrCubeMap );
-						hdrCubeMap.dispose();
+						hdrCubeRenderTarget = pmremGenerator.fromEquirectangular( hdrEquirect );
+						hdrEquirect.dispose();
 						pmremGenerator.dispose();
 
 						var bumpScale = 1;
@@ -170,6 +169,11 @@
 
 				//
 
+				var pmremGenerator = new PMREMGenerator( renderer );
+				pmremGenerator.compileEquirectangularShader();
+
+				//
+
 				stats = new Stats();
 				container.appendChild( stats.dom );
 

+ 3 - 1
examples/webgl_pmrem_test.html

@@ -133,7 +133,6 @@
 					.setPath( 'textures/equirectangular/' )
 					.load( 'spot1Lux.hdr', function ( texture ) {
 
-						var pmremGenerator = new PMREMGenerator( renderer );
 						radianceMap = pmremGenerator.fromEquirectangular( texture ).texture;
 						pmremGenerator.dispose();
 
@@ -166,6 +165,9 @@
 
 					} );
 
+				var pmremGenerator = new PMREMGenerator( renderer );
+				pmremGenerator.compileEquirectangularShader();
+
 			}
 
 			function onResize() {

+ 6 - 4
examples/webgl_tonemapping.html

@@ -135,17 +135,19 @@
 				new RGBELoader()
 					.setDataType( THREE.UnsignedByteType )
 					.setPath( 'textures/equirectangular/' )
-					.load( 'pedestrian_overpass_1k.hdr', function ( hdrCubeMap ) {
+					.load( 'pedestrian_overpass_1k.hdr', function ( hdrEquirect ) {
 
-						var pmremGenerator = new PMREMGenerator( renderer );
-						standardMaterial.envMap = pmremGenerator.fromCubemap( hdrCubeMap ).texture;
+						standardMaterial.envMap = pmremGenerator.fromEquirectangular( hdrEquirect ).texture;
 						standardMaterial.needsUpdate = true;
 
-						hdrCubeMap.dispose();
+						hdrEquirect.dispose();
 						pmremGenerator.dispose();
 
 					} );
 
+				var pmremGenerator = new PMREMGenerator( renderer );
+				pmremGenerator.compileEquirectangularShader();
+
 				// Lights
 
 				scene.add( new THREE.HemisphereLight( 0x111111, 0x000000 ) );

+ 10 - 6
src/renderers/webgl/WebGLPrograms.js

@@ -261,17 +261,21 @@ function WebGLPrograms( renderer, extensions, capabilities ) {
 
 		}
 
-		for ( var i = 0; i < parameterNames.length; i ++ ) {
+		if ( ! material.isRawShaderMaterial ) {
 
-			array.push( parameters[ parameterNames[ i ] ] );
+			for ( var i = 0; i < parameterNames.length; i ++ ) {
 
-		}
+				array.push( parameters[ parameterNames[ i ] ] );
 
-		array.push( material.onBeforeCompile.toString() );
+			}
+
+			array.push( renderer.outputEncoding );
 
-		array.push( renderer.outputEncoding );
+			array.push( renderer.gammaFactor );
 
-		array.push( renderer.gammaFactor );
+		}
+
+		array.push( material.onBeforeCompile.toString() );
 
 		return array.join();