Bläddra i källkod

WebGPURenderer: Prevent PMREM to break when missing textures (#27951)

* fix texture missing from env cubemap

* fix examples/webgpu_parallax_uv.html too
Renaud Rohlinger 1 år sedan
förälder
incheckning
bd2845f306

+ 16 - 0
examples/jsm/loaders/RGBMLoader.js

@@ -36,6 +36,12 @@ class RGBMLoader extends DataTextureLoader {
 
 		const texture = new CubeTexture();
 
+		for ( let i = 0; i < 6; i ++ ) {
+
+			texture.images[ i ] = undefined;
+
+		}
+
 		let loaded = 0;
 
 		const scope = this;
@@ -75,6 +81,16 @@ class RGBMLoader extends DataTextureLoader {
 
 	}
 
+	loadCubemapAsync( urls, onProgress ) {
+
+		return new Promise( ( resolve, reject ) => {
+
+			this.loadCubemap( urls, resolve, onProgress, reject );
+
+		} );
+
+	}
+
 	parse( buffer ) {
 
 		const img = UPNG.decode( buffer );

+ 12 - 0
examples/jsm/nodes/pmrem/PMREMNode.js

@@ -30,10 +30,22 @@ function _getPMREMFromTexture( texture ) {
 
 		if ( texture.isCubeTexture ) {
 
+			if ( texture.source.data.some( ( texture ) => texture === undefined ) ) {
+
+				throw new Error( 'PMREMNode: Undefined texture in CubeTexture. Use onLoad callback or async loader' );
+
+			}
+
 			cacheTexture = _generator.fromCubemap( texture );
 
 		} else {
 
+			if ( texture.image === undefined ) {
+
+				throw new Error( 'PMREMNode: Undefined image in Texture. Use onLoad callback or async loader' );
+
+			}
+
 			cacheTexture = _generator.fromEquirectangular( texture );
 
 		}

+ 6 - 6
examples/jsm/renderers/common/extras/PMREMGenerator.js

@@ -420,7 +420,7 @@ class PMREMGenerator {
 
 			if ( this._cubemapMaterial === null ) {
 
-				this._cubemapMaterial = _getCubemapMaterial();
+				this._cubemapMaterial = _getCubemapMaterial( texture );
 
 			}
 
@@ -428,7 +428,7 @@ class PMREMGenerator {
 
 			if ( this._equirectMaterial === null ) {
 
-				this._equirectMaterial = _getEquirectMaterial();
+				this._equirectMaterial = _getEquirectMaterial( texture );
 
 			}
 
@@ -736,19 +736,19 @@ function _getBlurShader( lodMax, width, height ) {
 
 }
 
-function _getCubemapMaterial() {
+function _getCubemapMaterial( envTexture ) {
 
 	const material = _getMaterial();
-	material.fragmentNode = cubeTexture( texture, outputDirection );
+	material.fragmentNode = cubeTexture( envTexture, outputDirection );
 
 	return material;
 
 }
 
-function _getEquirectMaterial() {
+function _getEquirectMaterial( envTexture ) {
 
 	const material = _getMaterial();
-	material.fragmentNode = texture( texture, equirectUV( outputDirection ), 0 );
+	material.fragmentNode = texture( envTexture, equirectUV( outputDirection ), 0 );
 
 	return material;
 

+ 7 - 9
examples/webgpu_cubemap_adjustments.html

@@ -45,7 +45,7 @@
 
 			init();
 
-			function init() {
+			async function init() {
 
 				if ( WebGPU.isAvailable() === false && WebGL.isWebGL2Available() === false ) {
 
@@ -68,18 +68,18 @@
 				// cube textures
 
 				const rgbmUrls = [ 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' ];
-				const cube1Texture = new RGBMLoader()
+				const cube1Texture = await new RGBMLoader()
 					.setMaxRange( 16 )
 					.setPath( './textures/cube/pisaRGBM16/' )
-					.loadCubemap( rgbmUrls );
+					.loadCubemapAsync( rgbmUrls );
 
 				cube1Texture.generateMipmaps = true;
 				cube1Texture.minFilter = THREE.LinearMipmapLinearFilter;
 
 				const cube2Urls = [ 'posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg' ];
-				const cube2Texture = new THREE.CubeTextureLoader()
+				const cube2Texture = await new THREE.CubeTextureLoader()
 					.setPath( './textures/cube/Park2/' )
-					.load( cube2Urls );
+					.loadAsync( cube2Urls );
 
 				cube2Texture.generateMipmaps = true;
 				cube2Texture.minFilter = THREE.LinearMipmapLinearFilter;
@@ -128,11 +128,9 @@
 				// scene objects
 
 				const loader = new GLTFLoader().setPath( 'models/gltf/DamagedHelmet/glTF/' );
-				loader.load( 'DamagedHelmet.gltf', function ( gltf ) {
+				const gltf = await loader.loadAsync( 'DamagedHelmet.gltf' );
 
-					scene.add( gltf.scene );
-
-				} );
+				scene.add( gltf.scene );
 
 				const sphereGeometry = new THREE.SphereGeometry( .5, 64, 32 );
 

+ 4 - 3
examples/webgpu_cubemap_dynamic.html

@@ -50,7 +50,7 @@
 
 			init();
 
-			function init() {
+			async function init() {
 
 				if ( WebGPU.isAvailable() === false && WebGL.isWebGL2Available() === false ) {
 
@@ -80,10 +80,10 @@
 				const uvTexture = new THREE.TextureLoader().load( './textures/uv_grid_opengl.jpg' );
 
 				const rgbmUrls = [ 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' ];
-				const texture = new RGBMLoader()
+				const texture = await new RGBMLoader()
 					.setMaxRange( 16 )
 					.setPath( './textures/cube/pisaRGBM16/' )
-					.loadCubemap( rgbmUrls );
+					.loadCubemapAsync( rgbmUrls );
 
 				texture.name = 'pisaRGBM16';
 				texture.minFilter = THREE.LinearMipmapLinearFilter;
@@ -150,6 +150,7 @@
 
 				const time = msTime / 1000;
 
+				if ( ! cube ) return;
 				cube.position.x = Math.cos( time ) * 30;
 				cube.position.y = Math.sin( time ) * 30;
 				cube.position.z = Math.sin( time ) * 30;

+ 5 - 7
examples/webgpu_cubemap_mix.html

@@ -43,7 +43,7 @@
 
 			init();
 
-			function init() {
+			async function init() {
 
 				if ( WebGPU.isAvailable() === false && WebGL.isWebGL2Available() === false ) {
 
@@ -71,9 +71,9 @@
 				cube1Texture.minFilter = THREE.LinearMipmapLinearFilter;
 
 				const cube2Urls = [ 'dark-s_px.jpg', 'dark-s_nx.jpg', 'dark-s_py.jpg', 'dark-s_ny.jpg', 'dark-s_pz.jpg', 'dark-s_nz.jpg' ];
-				const cube2Texture = new THREE.CubeTextureLoader()
+				const cube2Texture = await new THREE.CubeTextureLoader()
 					.setPath( './textures/cube/MilkyWay/' )
-					.load( cube2Urls );
+					.loadAsync( cube2Urls );
 
 				cube2Texture.generateMipmaps = true;
 				cube2Texture.minFilter = THREE.LinearMipmapLinearFilter;
@@ -85,11 +85,9 @@
 				} );
 
 				const loader = new GLTFLoader().setPath( 'models/gltf/DamagedHelmet/glTF/' );
-				loader.load( 'DamagedHelmet.gltf', function ( gltf ) {
+				const gltf = await loader.loadAsync( 'DamagedHelmet.gltf' );
 
-					scene.add( gltf.scene );
-
-				} );
+				scene.add( gltf.scene );
 
 				renderer = new WebGPURenderer( { antialias: true } );
 

+ 9 - 9
examples/webgpu_parallax_uv.html

@@ -39,7 +39,7 @@
 
 			init();
 
-			function init() {
+			async function init() {
 
 				// scene
 
@@ -52,9 +52,9 @@
 
 				// environment
 
-				const environmentTexture = new THREE.CubeTextureLoader()
+				const environmentTexture = await new THREE.CubeTextureLoader()
 					.setPath( './textures/cube/Park2/' )
-					.load( [ 'posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg' ] );
+					.loadAsync( [ 'posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg' ] );
 
 
 				scene.environment = environmentTexture;
@@ -64,21 +64,21 @@
 
 				const loader = new THREE.TextureLoader();
 
-				const topTexture = loader.load( 'textures/ambientcg/Ice002_1K-JPG_Color.jpg' );
+				const topTexture = await loader.loadAsync( 'textures/ambientcg/Ice002_1K-JPG_Color.jpg' );
 				topTexture.colorSpace = THREE.SRGBColorSpace;
 
-				const roughnessTexture = loader.load( 'textures/ambientcg/Ice002_1K-JPG_Roughness.jpg' );
+				const roughnessTexture = await loader.loadAsync( 'textures/ambientcg/Ice002_1K-JPG_Roughness.jpg' );
 				roughnessTexture.colorSpace = THREE.NoColorSpace;
 
-				const normalTexture = loader.load( 'textures/ambientcg/Ice002_1K-JPG_NormalGL.jpg' );
+				const normalTexture = await loader.loadAsync( 'textures/ambientcg/Ice002_1K-JPG_NormalGL.jpg' );
 				normalTexture.colorSpace = THREE.NoColorSpace;
 
-				const displaceTexture = loader.load( 'textures/ambientcg/Ice002_1K-JPG_Displacement.jpg' );
+				const displaceTexture = await loader.loadAsync( 'textures/ambientcg/Ice002_1K-JPG_Displacement.jpg' );
 				displaceTexture.colorSpace = THREE.NoColorSpace;
 
 				//
 
-				const bottomTexture = loader.load( 'textures/ambientcg/Ice003_1K-JPG_Color.jpg' );
+				const bottomTexture = await loader.loadAsync( 'textures/ambientcg/Ice003_1K-JPG_Color.jpg' );
 				bottomTexture.colorSpace = THREE.SRGBColorSpace;
 				bottomTexture.wrapS = THREE.RepeatWrapping;
 				bottomTexture.wrapT = THREE.RepeatWrapping;
@@ -109,7 +109,7 @@
 
 				// renderer
 
-				renderer = new WebGPURenderer( { antialias: true } );
+				renderer = new WebGPURenderer( { antialias: true, forceWebGL: false } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setAnimationLoop( animate );