Преглед изворни кода

WebGPURenderer: Fix filterable depth textures (#30023)

* fix filterable depth textures

* cleanup
sunag пре 1 година
родитељ
комит
ae2791a85e

BIN
examples/screenshots/webgpu_backdrop_water.jpg


+ 1 - 1
examples/webgpu_backdrop_water.html

@@ -191,7 +191,7 @@
 
 
 				// renderer
 				// renderer
 
 
-				renderer = new THREE.WebGPURenderer( /*{ antialias: true }*/ );
+				renderer = new THREE.WebGPURenderer( { antialias: true } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setAnimationLoop( animate );
 				renderer.setAnimationLoop( animate );

+ 18 - 0
src/core/RenderTarget.js

@@ -54,6 +54,7 @@ class RenderTarget extends EventDispatcher {
 
 
 			this.textures[ i ] = texture.clone();
 			this.textures[ i ] = texture.clone();
 			this.textures[ i ].isRenderTargetTexture = true;
 			this.textures[ i ].isRenderTargetTexture = true;
+			this.textures[ i ].renderTarget = this;
 
 
 		}
 		}
 
 
@@ -63,6 +64,7 @@ class RenderTarget extends EventDispatcher {
 		this.resolveDepthBuffer = options.resolveDepthBuffer;
 		this.resolveDepthBuffer = options.resolveDepthBuffer;
 		this.resolveStencilBuffer = options.resolveStencilBuffer;
 		this.resolveStencilBuffer = options.resolveStencilBuffer;
 
 
+		this._depthTexture = null;
 		this.depthTexture = options.depthTexture;
 		this.depthTexture = options.depthTexture;
 
 
 		this.samples = options.samples;
 		this.samples = options.samples;
@@ -81,6 +83,21 @@ class RenderTarget extends EventDispatcher {
 
 
 	}
 	}
 
 
+	set depthTexture( current ) {
+
+		if ( this._depthTexture !== null ) this._depthTexture.renderTarget = null;
+		if ( current !== null ) current.renderTarget = this;
+
+		this._depthTexture = current;
+
+	}
+
+	get depthTexture() {
+
+		return this._depthTexture;
+
+	}
+
 	setSize( width, height, depth = 1 ) {
 	setSize( width, height, depth = 1 ) {
 
 
 		if ( this.width !== width || this.height !== height || this.depth !== depth ) {
 		if ( this.width !== width || this.height !== height || this.depth !== depth ) {
@@ -129,6 +146,7 @@ class RenderTarget extends EventDispatcher {
 
 
 			this.textures[ i ] = source.textures[ i ].clone();
 			this.textures[ i ] = source.textures[ i ].clone();
 			this.textures[ i ].isRenderTargetTexture = true;
 			this.textures[ i ].isRenderTargetTexture = true;
+			this.textures[ i ].renderTarget = this;
 
 
 		}
 		}
 
 

+ 0 - 4
src/nodes/display/PassNode.js

@@ -169,7 +169,6 @@ class PassNode extends TempNode {
 			const refTexture = this.renderTarget.texture;
 			const refTexture = this.renderTarget.texture;
 
 
 			texture = refTexture.clone();
 			texture = refTexture.clone();
-			texture.isRenderTargetTexture = true;
 			texture.name = name;
 			texture.name = name;
 
 
 			this._textures[ name ] = texture;
 			this._textures[ name ] = texture;
@@ -189,7 +188,6 @@ class PassNode extends TempNode {
 		if ( texture === undefined ) {
 		if ( texture === undefined ) {
 
 
 			texture = this.getTexture( name ).clone();
 			texture = this.getTexture( name ).clone();
-			texture.isRenderTargetTexture = true;
 
 
 			this._previousTextures[ name ] = texture;
 			this._previousTextures[ name ] = texture;
 
 
@@ -302,8 +300,6 @@ class PassNode extends TempNode {
 
 
 		}
 		}
 
 
-		this.renderTarget.depthTexture.isMultisampleRenderTargetTexture = this.renderTarget.samples > 1;
-
 		return this.scope === PassNode.COLOR ? this.getTextureNode() : this.getLinearDepthNode();
 		return this.scope === PassNode.COLOR ? this.getTextureNode() : this.getLinearDepthNode();
 
 
 	}
 	}

+ 7 - 3
src/renderers/webgpu/nodes/WGSLNodeBuilder.js

@@ -311,7 +311,9 @@ class WGSLNodeBuilder extends NodeBuilder {
 
 
 			let textureDimensionsParams;
 			let textureDimensionsParams;
 
 
-			if ( texture.isMultisampleRenderTargetTexture === true ) {
+			const { primarySamples } = this.renderer.backend.utils.getTextureSampleData( texture );
+
+			if ( primarySamples > 1 ) {
 
 
 				textureDimensionsParams = textureProperty;
 				textureDimensionsParams = textureProperty;
 
 
@@ -388,7 +390,7 @@ class WGSLNodeBuilder extends NodeBuilder {
 		return this.getComponentTypeFromTexture( texture ) !== 'float' ||
 		return this.getComponentTypeFromTexture( texture ) !== 'float' ||
 			( ! this.isAvailable( 'float32Filterable' ) && texture.isDataTexture === true && texture.type === FloatType ) ||
 			( ! this.isAvailable( 'float32Filterable' ) && texture.isDataTexture === true && texture.type === FloatType ) ||
 			( this.isSampleCompare( texture ) === false && texture.minFilter === NearestFilter && texture.magFilter === NearestFilter ) ||
 			( this.isSampleCompare( texture ) === false && texture.minFilter === NearestFilter && texture.magFilter === NearestFilter ) ||
-			texture.isMultisampleRenderTargetTexture === true;
+			this.renderer.backend.utils.getTextureSampleData( texture ).primarySamples > 1;
 
 
 	}
 	}
 
 
@@ -1120,7 +1122,9 @@ ${ flowData.code }
 
 
 				let multisampled = '';
 				let multisampled = '';
 
 
-				if ( texture.isMultisampleRenderTargetTexture === true ) {
+				const { primarySamples } = this.renderer.backend.utils.getTextureSampleData( texture );
+
+				if ( primarySamples > 1 ) {
 
 
 					multisampled = '_multisampled';
 					multisampled = '_multisampled';
 
 

+ 9 - 1
src/renderers/webgpu/utils/WebGPUBindingUtils.js

@@ -107,10 +107,18 @@ class WebGPUBindingUtils {
 
 
 				const texture = {}; // GPUTextureBindingLayout
 				const texture = {}; // GPUTextureBindingLayout
 
 
-				if ( binding.texture.isMultisampleRenderTargetTexture === true ) {
+				const { primarySamples } = backend.utils.getTextureSampleData( binding.texture );
+
+				if ( primarySamples > 1 ) {
 
 
 					texture.multisampled = true;
 					texture.multisampled = true;
 
 
+					if ( ! binding.texture.isDepthTexture ) {
+
+						texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
+
+					}
+
 				}
 				}
 
 
 				if ( binding.texture.isDepthTexture ) {
 				if ( binding.texture.isDepthTexture ) {

+ 5 - 9
src/renderers/webgpu/utils/WebGPUTextureUtils.js

@@ -146,11 +146,7 @@ class WebGPUTextureUtils {
 
 
 		textureData.format = format;
 		textureData.format = format;
 
 
-		let sampleCount = options.sampleCount !== undefined ? options.sampleCount : 1;
-
-		sampleCount = backend.utils.getSampleCount( sampleCount );
-
-		const primarySampleCount = texture.isRenderTargetTexture && ! texture.isMultisampleRenderTargetTexture ? 1 : sampleCount;
+		const { samples, primarySamples, isMSAA } = backend.utils.getTextureSampleData( texture );
 
 
 		let usage = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC;
 		let usage = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC;
 
 
@@ -174,7 +170,7 @@ class WebGPUTextureUtils {
 				depthOrArrayLayers: depth,
 				depthOrArrayLayers: depth,
 			},
 			},
 			mipLevelCount: levels,
 			mipLevelCount: levels,
-			sampleCount: primarySampleCount,
+			sampleCount: primarySamples,
 			dimension: dimension,
 			dimension: dimension,
 			format: format,
 			format: format,
 			usage: usage
 			usage: usage
@@ -208,12 +204,12 @@ class WebGPUTextureUtils {
 
 
 		}
 		}
 
 
-		if ( texture.isRenderTargetTexture && sampleCount > 1 && ! texture.isMultisampleRenderTargetTexture ) {
+		if ( isMSAA ) {
 
 
 			const msaaTextureDescriptorGPU = Object.assign( {}, textureDescriptorGPU );
 			const msaaTextureDescriptorGPU = Object.assign( {}, textureDescriptorGPU );
 
 
 			msaaTextureDescriptorGPU.label = msaaTextureDescriptorGPU.label + '-msaa';
 			msaaTextureDescriptorGPU.label = msaaTextureDescriptorGPU.label + '-msaa';
-			msaaTextureDescriptorGPU.sampleCount = sampleCount;
+			msaaTextureDescriptorGPU.sampleCount = samples;
 
 
 			textureData.msaaTexture = backend.device.createTexture( msaaTextureDescriptorGPU );
 			textureData.msaaTexture = backend.device.createTexture( msaaTextureDescriptorGPU );
 
 
@@ -336,7 +332,7 @@ class WebGPUTextureUtils {
 		depthTexture.image.width = width;
 		depthTexture.image.width = width;
 		depthTexture.image.height = height;
 		depthTexture.image.height = height;
 
 
-		this.createTexture( depthTexture, { sampleCount: backend.utils.getSampleCount( backend.renderer.samples ), width, height } );
+		this.createTexture( depthTexture, { width, height } );
 
 
 		return backend.get( depthTexture ).texture;
 		return backend.get( depthTexture ).texture;
 
 

+ 30 - 0
src/renderers/webgpu/utils/WebGPUUtils.js

@@ -36,6 +36,36 @@ class WebGPUUtils {
 
 
 	}
 	}
 
 
+	getTextureSampleData( texture ) {
+
+		let samples;
+
+		if ( texture.isFramebufferTexture ) {
+
+			samples = 1;
+
+		} else if ( texture.isDepthTexture && ! texture.renderTarget ) {
+
+			const renderer = this.backend.renderer;
+			const renderTarget = renderer.getRenderTarget();
+
+			samples = renderTarget ? renderTarget.samples : renderer.samples;
+
+		} else if ( texture.renderTarget ) {
+
+			samples = texture.renderTarget.samples;
+
+		}
+
+		samples = samples || 1;
+
+		const isMSAA = samples > 1 && texture.renderTarget !== null && ( texture.isDepthTexture !== true && texture.isFramebufferTexture !== true );
+		const primarySamples = isMSAA ? 1 : samples;
+
+		return { samples, primarySamples, isMSAA };
+
+	}
+
 	getCurrentColorFormat( renderContext ) {
 	getCurrentColorFormat( renderContext ) {
 
 
 		let format;
 		let format;

+ 4 - 0
src/textures/Texture.js

@@ -69,6 +69,7 @@ class Texture extends EventDispatcher {
 		this.version = 0;
 		this.version = 0;
 		this.onUpdate = null;
 		this.onUpdate = null;
 
 
+		this.renderTarget = null; // assign texture to a render target
 		this.isRenderTargetTexture = false; // indicates whether a texture belongs to a render target or not
 		this.isRenderTargetTexture = false; // indicates whether a texture belongs to a render target or not
 		this.pmremVersion = 0; // indicates whether this texture should be processed by PMREMGenerator or not (only relevant for render target textures)
 		this.pmremVersion = 0; // indicates whether this texture should be processed by PMREMGenerator or not (only relevant for render target textures)
 
 
@@ -134,6 +135,9 @@ class Texture extends EventDispatcher {
 		this.unpackAlignment = source.unpackAlignment;
 		this.unpackAlignment = source.unpackAlignment;
 		this.colorSpace = source.colorSpace;
 		this.colorSpace = source.colorSpace;
 
 
+		this.renderTarget = source.renderTarget;
+		this.isRenderTargetTexture = source.isRenderTargetTexture;
+
 		this.userData = JSON.parse( JSON.stringify( source.userData ) );
 		this.userData = JSON.parse( JSON.stringify( source.userData ) );
 
 
 		this.needsUpdate = true;
 		this.needsUpdate = true;

粤ICP备19079148号