Browse Source

WebGPURenderer: Fix DataTexture - FloatType (#26585)

sunag 1 năm trước cách đây
mục cha
commit
c849b5da3c

+ 33 - 23
examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js

@@ -1,4 +1,4 @@
-import { RenderTarget, NoColorSpace } from 'three';
+import { RenderTarget, NoColorSpace, FloatType } from 'three';
 
 import UniformsGroup from '../../common/UniformsGroup.js';
 import {
@@ -136,7 +136,7 @@ class WGSLNodeBuilder extends NodeBuilder {
 
 	}
 
-	getSampler( textureProperty, uvSnippet, shaderStage = this.shaderStage ) {
+	_getSampler( texture, textureProperty, uvSnippet, shaderStage = this.shaderStage ) {
 
 		if ( shaderStage === 'fragment' ) {
 
@@ -144,17 +144,13 @@ class WGSLNodeBuilder extends NodeBuilder {
 
 		} else {
 
-			this._include( 'repeatWrapping' );
-
-			const dimension = `textureDimensions( ${textureProperty}, 0 )`;
-
-			return `textureLoad( ${textureProperty}, threejs_repeatWrapping( ${uvSnippet}, ${dimension} ), 0 )`;
+			return this.getTextureLoad( texture, textureProperty, uvSnippet );
 
 		}
 
 	}
 
-	getVideoSampler( textureProperty, uvSnippet, shaderStage = this.shaderStage ) {
+	_getVideoSampler( textureProperty, uvSnippet, shaderStage = this.shaderStage ) {
 
 		if ( shaderStage === 'fragment' ) {
 
@@ -168,21 +164,33 @@ class WGSLNodeBuilder extends NodeBuilder {
 
 	}
 
-	getSamplerLevel( textureProperty, uvSnippet, biasSnippet, shaderStage = this.shaderStage ) {
+	_getSamplerLevel( texture, textureProperty, uvSnippet, biasSnippet, shaderStage = this.shaderStage ) {
 
-		if ( shaderStage === 'fragment' ) {
+		if ( shaderStage === 'fragment' && this.isUnfilterable( texture ) === false ) {
 
 			return `textureSampleLevel( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${biasSnippet} )`;
 
 		} else {
 
-			this._include( 'repeatWrapping' );
+			return this.getTextureLoad( texture, textureProperty, uvSnippet, biasSnippet );
 
-			const dimension = `textureDimensions( ${textureProperty}, 0 )`;
+		}
 
-			return `textureLoad( ${textureProperty}, threejs_repeatWrapping( ${uvSnippet}, ${dimension} ), i32( ${biasSnippet} ) )`;
+	}
 
-		}
+	getTextureLoad( texture, textureProperty, uvSnippet, biasSnippet = '0' ) {
+
+		this._include( 'repeatWrapping' );
+
+		const dimension = `textureDimensions( ${textureProperty}, 0 )`;
+
+		return `textureLoad( ${textureProperty}, threejs_repeatWrapping( ${uvSnippet}, ${dimension} ), i32( ${biasSnippet} ) )`;
+
+	}
+
+	isUnfilterable( texture ) {
+
+		return texture.isDataTexture === true && texture.type === FloatType;
 
 	}
 
@@ -192,11 +200,15 @@ class WGSLNodeBuilder extends NodeBuilder {
 
 		if ( texture.isVideoTexture === true ) {
 
-			snippet = this.getVideoSampler( textureProperty, uvSnippet, shaderStage );
+			snippet = this._getVideoSampler( textureProperty, uvSnippet, shaderStage );
+
+		} else if ( this.isUnfilterable( texture ) ) {
+
+			snippet = this.getTextureLoad( texture, textureProperty, uvSnippet );
 
 		} else {
 
-			snippet = this.getSampler( textureProperty, uvSnippet, shaderStage );
+			snippet = this._getSampler( texture, textureProperty, uvSnippet, shaderStage );
 
 		}
 
@@ -224,11 +236,11 @@ class WGSLNodeBuilder extends NodeBuilder {
 
 		if ( texture.isVideoTexture === true ) {
 
-			snippet = this.getVideoSampler( textureProperty, uvSnippet, shaderStage );
+			snippet = this._getVideoSampler( textureProperty, uvSnippet, shaderStage );
 
 		} else {
 
-			snippet = this.getSamplerLevel( textureProperty, uvSnippet, biasSnippet, shaderStage );
+			snippet = this._getSamplerLevel( texture, textureProperty, uvSnippet, biasSnippet, shaderStage );
 
 		}
 
@@ -302,7 +314,7 @@ class WGSLNodeBuilder extends NodeBuilder {
 				const lastBinding = bindings[ bindings.length - 1 ];
 				const index = lastBinding && lastBinding.isUniformsGroup ? bindings.length - 1 : bindings.length;
 
-				if ( shaderStage === 'fragment' ) {
+				if ( shaderStage === 'fragment' && this.isUnfilterable( node.value ) === false ) {
 
 					const sampler = new NodeSampler( `${uniformNode.name}_sampler`, uniformNode.node );
 					sampler.setVisibility( gpuShaderStageLib[ shaderStage ] );
@@ -580,9 +592,9 @@ class WGSLNodeBuilder extends NodeBuilder {
 
 			if ( uniform.type === 'texture' || uniform.type === 'cubeTexture' ) {
 
-				if ( shaderStage === 'fragment' ) {
+				const texture = uniform.node.value;
 
-					const texture = uniform.node.value;
+				if ( shaderStage === 'fragment' && this.isUnfilterable( texture ) === false ) {
 
 					if ( texture.isDepthTexture === true && texture.compareFunction !== null ) {
 
@@ -596,8 +608,6 @@ class WGSLNodeBuilder extends NodeBuilder {
 
 				}
 
-				const texture = uniform.node.value;
-
 				let textureType;
 
 				if ( texture.isCubeTexture === true ) {

+ 9 - 2
examples/jsm/renderers/webgpu/utils/WebGPUBindingUtils.js

@@ -1,6 +1,7 @@
 import {
-	GPUTextureAspect, GPUTextureViewDimension, GPUBufferBindingType
+	GPUTextureAspect, GPUTextureViewDimension, GPUBufferBindingType, GPUTextureSampleType
 } from './WebGPUConstants.js';
+import { FloatType } from 'three';
 
 class WebGPUBindingUtils {
 
@@ -64,7 +65,13 @@ class WebGPUBindingUtils {
 
 				if ( binding.texture.isDepthTexture ) {
 
-					texture.sampleType = 'depth';
+					texture.sampleType = GPUTextureSampleType.Depth;
+
+				} else if ( binding.texture.isDataTexture && binding.texture.type === FloatType ) {
+
+					// @TODO: Add support for this soon: backend.hasFeature( 'float32-filterable' )
+
+					texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
 
 				}