瀏覽代碼

WebGPURenderer, CubeCamera: Add `.activeMipmapLevel` (#26770)

* CubeCamera: Add .activeMipmapLevel

* Use CubeCamera

* WebGPURenderer:  Add .activeMipmapLevel for set .setRenderTarget()
sunag 1 年之前
父節點
當前提交
18febaf042

+ 25 - 3
examples/jsm/renderers/common/Renderer.js

@@ -83,7 +83,8 @@ class Renderer {
 		this._clearStencil = 0;
 
 		this._renderTarget = null;
-		this._currentActiveCubeFace = 0;
+		this._activeCubeFace = 0;
+		this._activeMipmapLevel = 0;
 
 		this._initialized = false;
 		this._initPromise = null;
@@ -187,6 +188,7 @@ class Renderer {
 		const renderTarget = this._renderTarget;
 		const renderContext = this._renderContexts.get( scene, camera, renderTarget );
 		const activeCubeFace = this._activeCubeFace;
+		const activeMipmapLevel = this._activeMipmapLevel;
 
 		this._currentRenderContext = renderContext;
 
@@ -238,12 +240,16 @@ class Renderer {
 		const maxDepth = ( viewport.maxDepth === undefined ) ? 1 : viewport.maxDepth;
 
 		renderContext.viewportValue.copy( viewport ).multiplyScalar( pixelRatio ).floor();
+		renderContext.viewportValue.width >>= activeMipmapLevel;
+		renderContext.viewportValue.height >>= activeMipmapLevel;
 		renderContext.viewportValue.minDepth = minDepth;
 		renderContext.viewportValue.maxDepth = maxDepth;
 		renderContext.viewport = renderContext.viewportValue.equals( _screen ) === false;
 
 		renderContext.scissorValue.copy( scissor ).multiplyScalar( pixelRatio ).floor();
 		renderContext.scissor = this._scissorTest && renderContext.scissorValue.equals( _screen ) === false;
+		renderContext.scissorValue.width >>= activeMipmapLevel;
+		renderContext.scissorValue.height >>= activeMipmapLevel;
 
 		renderContext.depth = this.depth;
 		renderContext.stencil = this.stencil;
@@ -274,7 +280,7 @@ class Renderer {
 
 		if ( renderTarget !== null ) {
 
-			this._textures.updateRenderTarget( renderTarget );
+			this._textures.updateRenderTarget( renderTarget, activeMipmapLevel );
 
 			const renderTargetData = this._textures.get( renderTarget );
 
@@ -292,7 +298,10 @@ class Renderer {
 
 		}
 
+		renderContext.width >>= activeMipmapLevel;
+		renderContext.height >>= activeMipmapLevel;
 		renderContext.activeCubeFace = activeCubeFace;
+		renderContext.activeMipmapLevel = activeMipmapLevel;
 		renderContext.occlusionQueryCount = renderList.occlusionQueryCount;
 
 		//
@@ -333,6 +342,18 @@ class Renderer {
 
 	}
 
+	getActiveCubeFace() {
+
+		return this._activeCubeFace;
+
+	}
+
+	getActiveMipmapLevel() {
+
+		return this._activeMipmapLevel;
+
+	}
+
 	setAnimationLoop( callback ) {
 
 		if ( this._initialized === false ) this.init();
@@ -606,10 +627,11 @@ class Renderer {
 
 	}
 
-	setRenderTarget( renderTarget, activeCubeFace = 0 ) {
+	setRenderTarget( renderTarget, activeCubeFace = 0, activeMipmapLevel = 0 ) {
 
 		this._renderTarget = renderTarget;
 		this._activeCubeFace = activeCubeFace;
+		this._activeMipmapLevel = activeMipmapLevel;
 
 	}
 

+ 13 - 6
examples/jsm/renderers/common/Textures.js

@@ -15,10 +15,12 @@ class Textures extends DataMap {
 
 	}
 
-	updateRenderTarget( renderTarget ) {
+	updateRenderTarget( renderTarget, activeMipmapLevel = 0 ) {
 
 		const renderTargetData = this.get( renderTarget );
+
 		const sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples;
+		const depthTextureMips = renderTargetData.depthTextureMips || ( renderTargetData.depthTextureMips = {} );
 
 		let texture, textures;
 
@@ -36,7 +38,10 @@ class Textures extends DataMap {
 
 		const size = this.getSize( texture );
 
-		let depthTexture = renderTarget.depthTexture || renderTargetData.depthTexture;
+		const mipWidth = size.width >> activeMipmapLevel;
+		const mipHeight = size.height >> activeMipmapLevel;
+
+		let depthTexture = renderTarget.depthTexture || depthTextureMips[ activeMipmapLevel ];
 		let textureNeedsUpdate = false;
 
 		if ( depthTexture === undefined ) {
@@ -44,8 +49,10 @@ class Textures extends DataMap {
 			depthTexture = new DepthTexture();
 			depthTexture.format = DepthStencilFormat;
 			depthTexture.type = UnsignedInt248Type;
-			depthTexture.image.width = size.width;
-			depthTexture.image.height = size.height;
+			depthTexture.image.width = mipWidth;
+			depthTexture.image.height = mipHeight;
+
+			depthTextureMips[ activeMipmapLevel ] = depthTexture;
 
 		}
 
@@ -54,8 +61,8 @@ class Textures extends DataMap {
 			textureNeedsUpdate = true;
 			depthTexture.needsUpdate = true;
 
-			depthTexture.image.width = size.width;
-			depthTexture.image.height = size.height;
+			depthTexture.image.width = mipWidth;
+			depthTexture.image.height = mipHeight;
 
 		}
 

+ 1 - 1
examples/jsm/renderers/webgpu/WebGPUBackend.js

@@ -191,7 +191,7 @@ class WebGPUBackend extends Backend {
 				const textureData = this.get( textures[ i ] );
 
 				const textureView = textureData.texture.createView( {
-					baseMipLevel: 0,
+					baseMipLevel: renderContext.activeMipmapLevel,
 					mipLevelCount: 1,
 					baseArrayLayer: renderContext.activeCubeFace,
 					dimension: GPUTextureViewDimension.TwoD

+ 8 - 45
examples/webgl_materials_cubemap_render_to_mipmaps.html

@@ -127,30 +127,6 @@
 
 			function renderToCubeTexture( cubeMapRenderTarget, sourceCubeTexture ) {
 
-				const cameras = [];
-
-				for ( let i = 0; i < 6; i ++ ) {
-
-					// negative fov is not an error
-					cameras.push( new THREE.PerspectiveCamera( - 90, 1, 1, 10 ) );
-
-				}
-
-				cameras[ 0 ].up.set( 0, 1, 0 );
-				cameras[ 0 ].lookAt( 1, 0, 0 );
-				cameras[ 1 ].up.set( 0, 1, 0 );
-				cameras[ 1 ].lookAt( - 1, 0, 0 );
-				cameras[ 2 ].up.set( 0, 0, - 1 );
-				cameras[ 2 ].lookAt( 0, 1, 0 );
-				cameras[ 3 ].up.set( 0, 0, 1 );
-				cameras[ 3 ].lookAt( 0, - 1, 0 );
-				cameras[ 4 ].up.set( 0, 1, 0 );
-				cameras[ 4 ].lookAt( 0, 0, 1 );
-				cameras[ 5 ].up.set( 0, 1, 0 );
-				cameras[ 5 ].lookAt( 0, 0, - 1 );
-
-				for ( let i = 0; i < 6; i ++ ) cameras[ i ].updateMatrixWorld();
-
 				const geometry = new THREE.BoxGeometry( 5, 5, 5 );
 
 				const material = new THREE.ShaderMaterial( {
@@ -165,34 +141,21 @@
 				material.uniforms.cubeTexture.value = sourceCubeTexture;
 
 				const mesh = new THREE.Mesh( geometry, material );
+				const cubeCamera = new THREE.CubeCamera( 1, 10, cubeMapRenderTarget );
+				const mipmapCount = Math.floor( Math.log2( Math.max( cubeMapRenderTarget.width, cubeMapRenderTarget.height ) ) );
 
-				const currentRenderTarget = renderer.getRenderTarget();
-				const currentXrEnabled = renderer.xr.enabled;
-				renderer.xr.enabled = false;
-
-				for ( let faceIndex = 0; faceIndex < 6; faceIndex ++ ) {
+				for ( let mipmap = 0; mipmap < mipmapCount; mipmap ++ ) {
 
-					let mipIndex = 0;
-					let mipSize = cubeMapRenderTarget.width;
+					material.uniforms.mipIndex.value = mipmap;
+					material.needsUpdate = true;
 
-					// Render to each texture mip level
-					while ( mipSize >= 1 ) {
+					cubeMapRenderTarget.viewport.set( 0, 0, cubeMapRenderTarget.width >> mipmap, cubeMapRenderTarget.height >> mipmap );
 
-						cubeMapRenderTarget.viewport.set( 0, 0, mipSize, mipSize );
-						renderer.setRenderTarget( cubeMapRenderTarget, faceIndex, mipIndex );
-						material.uniforms.mipIndex.value = mipIndex;
-						material.needsUpdate = true;
-						renderer.render( mesh, cameras[ faceIndex ] );
-						mipSize >>= 1;
-						mipIndex ++;
-
-					}
+					cubeCamera.activeMipmapLevel = mipmap;
+					cubeCamera.update( renderer, mesh );
 
 				}
 
-				renderer.setRenderTarget( currentRenderTarget );
-				renderer.xr.enabled = currentXrEnabled;
-
 				mesh.geometry.dispose();
 				mesh.material.dispose();
 

+ 11 - 8
src/cameras/CubeCamera.js

@@ -15,6 +15,7 @@ class CubeCamera extends Object3D {
 
 		this.renderTarget = renderTarget;
 		this.coordinateSystem = null;
+		this.activeMipmapLevel = 0;
 
 		const cameraPX = new PerspectiveCamera( fov, aspect, near, far );
 		cameraPX.layers = this.layers;
@@ -112,7 +113,7 @@ class CubeCamera extends Object3D {
 
 		if ( this.parent === null ) this.updateMatrixWorld();
 
-		const renderTarget = this.renderTarget;
+		const { renderTarget, activeMipmapLevel } = this;
 
 		if ( this.coordinateSystem !== renderer.coordinateSystem ) {
 
@@ -125,6 +126,8 @@ class CubeCamera extends Object3D {
 		const [ cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ ] = this.children;
 
 		const currentRenderTarget = renderer.getRenderTarget();
+		const currentActiveCubeFace = renderer.getActiveCubeFace();
+		const currentActiveMipmapLevel = renderer.getActiveMipmapLevel();
 
 		const currentXrEnabled = renderer.xr.enabled;
 
@@ -134,19 +137,19 @@ class CubeCamera extends Object3D {
 
 		renderTarget.texture.generateMipmaps = false;
 
-		renderer.setRenderTarget( renderTarget, 0 );
+		renderer.setRenderTarget( renderTarget, 0, activeMipmapLevel );
 		renderer.render( scene, cameraPX );
 
-		renderer.setRenderTarget( renderTarget, 1 );
+		renderer.setRenderTarget( renderTarget, 1, activeMipmapLevel );
 		renderer.render( scene, cameraNX );
 
-		renderer.setRenderTarget( renderTarget, 2 );
+		renderer.setRenderTarget( renderTarget, 2, activeMipmapLevel );
 		renderer.render( scene, cameraPY );
 
-		renderer.setRenderTarget( renderTarget, 3 );
+		renderer.setRenderTarget( renderTarget, 3, activeMipmapLevel );
 		renderer.render( scene, cameraNY );
 
-		renderer.setRenderTarget( renderTarget, 4 );
+		renderer.setRenderTarget( renderTarget, 4, activeMipmapLevel );
 		renderer.render( scene, cameraPZ );
 
 		// mipmaps are generated during the last call of render()
@@ -154,10 +157,10 @@ class CubeCamera extends Object3D {
 
 		renderTarget.texture.generateMipmaps = generateMipmaps;
 
-		renderer.setRenderTarget( renderTarget, 5 );
+		renderer.setRenderTarget( renderTarget, 5, activeMipmapLevel );
 		renderer.render( scene, cameraNZ );
 
-		renderer.setRenderTarget( currentRenderTarget );
+		renderer.setRenderTarget( currentRenderTarget, currentActiveCubeFace, currentActiveMipmapLevel );
 
 		renderer.xr.enabled = currentXrEnabled;