Skip to content

Commit ae2791a

Browse files
authored
WebGPURenderer: Fix filterable depth textures (#30023)
* fix filterable depth textures * cleanup
1 parent 93dccc1 commit ae2791a

File tree

9 files changed

+74
-18
lines changed

9 files changed

+74
-18
lines changed
58.5 KB
Loading

examples/webgpu_backdrop_water.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@
191191

192192
// renderer
193193

194-
renderer = new THREE.WebGPURenderer( /*{ antialias: true }*/ );
194+
renderer = new THREE.WebGPURenderer( { antialias: true } );
195195
renderer.setPixelRatio( window.devicePixelRatio );
196196
renderer.setSize( window.innerWidth, window.innerHeight );
197197
renderer.setAnimationLoop( animate );

src/core/RenderTarget.js

+18
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class RenderTarget extends EventDispatcher {
5454

5555
this.textures[ i ] = texture.clone();
5656
this.textures[ i ].isRenderTargetTexture = true;
57+
this.textures[ i ].renderTarget = this;
5758

5859
}
5960

@@ -63,6 +64,7 @@ class RenderTarget extends EventDispatcher {
6364
this.resolveDepthBuffer = options.resolveDepthBuffer;
6465
this.resolveStencilBuffer = options.resolveStencilBuffer;
6566

67+
this._depthTexture = null;
6668
this.depthTexture = options.depthTexture;
6769

6870
this.samples = options.samples;
@@ -81,6 +83,21 @@ class RenderTarget extends EventDispatcher {
8183

8284
}
8385

86+
set depthTexture( current ) {
87+
88+
if ( this._depthTexture !== null ) this._depthTexture.renderTarget = null;
89+
if ( current !== null ) current.renderTarget = this;
90+
91+
this._depthTexture = current;
92+
93+
}
94+
95+
get depthTexture() {
96+
97+
return this._depthTexture;
98+
99+
}
100+
84101
setSize( width, height, depth = 1 ) {
85102

86103
if ( this.width !== width || this.height !== height || this.depth !== depth ) {
@@ -129,6 +146,7 @@ class RenderTarget extends EventDispatcher {
129146

130147
this.textures[ i ] = source.textures[ i ].clone();
131148
this.textures[ i ].isRenderTargetTexture = true;
149+
this.textures[ i ].renderTarget = this;
132150

133151
}
134152

src/nodes/display/PassNode.js

-4
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,6 @@ class PassNode extends TempNode {
169169
const refTexture = this.renderTarget.texture;
170170

171171
texture = refTexture.clone();
172-
texture.isRenderTargetTexture = true;
173172
texture.name = name;
174173

175174
this._textures[ name ] = texture;
@@ -189,7 +188,6 @@ class PassNode extends TempNode {
189188
if ( texture === undefined ) {
190189

191190
texture = this.getTexture( name ).clone();
192-
texture.isRenderTargetTexture = true;
193191

194192
this._previousTextures[ name ] = texture;
195193

@@ -302,8 +300,6 @@ class PassNode extends TempNode {
302300

303301
}
304302

305-
this.renderTarget.depthTexture.isMultisampleRenderTargetTexture = this.renderTarget.samples > 1;
306-
307303
return this.scope === PassNode.COLOR ? this.getTextureNode() : this.getLinearDepthNode();
308304

309305
}

src/renderers/webgpu/nodes/WGSLNodeBuilder.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,9 @@ class WGSLNodeBuilder extends NodeBuilder {
311311

312312
let textureDimensionsParams;
313313

314-
if ( texture.isMultisampleRenderTargetTexture === true ) {
314+
const { primarySamples } = this.renderer.backend.utils.getTextureSampleData( texture );
315+
316+
if ( primarySamples > 1 ) {
315317

316318
textureDimensionsParams = textureProperty;
317319

@@ -388,7 +390,7 @@ class WGSLNodeBuilder extends NodeBuilder {
388390
return this.getComponentTypeFromTexture( texture ) !== 'float' ||
389391
( ! this.isAvailable( 'float32Filterable' ) && texture.isDataTexture === true && texture.type === FloatType ) ||
390392
( this.isSampleCompare( texture ) === false && texture.minFilter === NearestFilter && texture.magFilter === NearestFilter ) ||
391-
texture.isMultisampleRenderTargetTexture === true;
393+
this.renderer.backend.utils.getTextureSampleData( texture ).primarySamples > 1;
392394

393395
}
394396

@@ -1120,7 +1122,9 @@ ${ flowData.code }
11201122

11211123
let multisampled = '';
11221124

1123-
if ( texture.isMultisampleRenderTargetTexture === true ) {
1125+
const { primarySamples } = this.renderer.backend.utils.getTextureSampleData( texture );
1126+
1127+
if ( primarySamples > 1 ) {
11241128

11251129
multisampled = '_multisampled';
11261130

src/renderers/webgpu/utils/WebGPUBindingUtils.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,18 @@ class WebGPUBindingUtils {
107107

108108
const texture = {}; // GPUTextureBindingLayout
109109

110-
if ( binding.texture.isMultisampleRenderTargetTexture === true ) {
110+
const { primarySamples } = backend.utils.getTextureSampleData( binding.texture );
111+
112+
if ( primarySamples > 1 ) {
111113

112114
texture.multisampled = true;
113115

116+
if ( ! binding.texture.isDepthTexture ) {
117+
118+
texture.sampleType = GPUTextureSampleType.UnfilterableFloat;
119+
120+
}
121+
114122
}
115123

116124
if ( binding.texture.isDepthTexture ) {

src/renderers/webgpu/utils/WebGPUTextureUtils.js

+5-9
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,7 @@ class WebGPUTextureUtils {
146146

147147
textureData.format = format;
148148

149-
let sampleCount = options.sampleCount !== undefined ? options.sampleCount : 1;
150-
151-
sampleCount = backend.utils.getSampleCount( sampleCount );
152-
153-
const primarySampleCount = texture.isRenderTargetTexture && ! texture.isMultisampleRenderTargetTexture ? 1 : sampleCount;
149+
const { samples, primarySamples, isMSAA } = backend.utils.getTextureSampleData( texture );
154150

155151
let usage = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC;
156152

@@ -174,7 +170,7 @@ class WebGPUTextureUtils {
174170
depthOrArrayLayers: depth,
175171
},
176172
mipLevelCount: levels,
177-
sampleCount: primarySampleCount,
173+
sampleCount: primarySamples,
178174
dimension: dimension,
179175
format: format,
180176
usage: usage
@@ -208,12 +204,12 @@ class WebGPUTextureUtils {
208204

209205
}
210206

211-
if ( texture.isRenderTargetTexture && sampleCount > 1 && ! texture.isMultisampleRenderTargetTexture ) {
207+
if ( isMSAA ) {
212208

213209
const msaaTextureDescriptorGPU = Object.assign( {}, textureDescriptorGPU );
214210

215211
msaaTextureDescriptorGPU.label = msaaTextureDescriptorGPU.label + '-msaa';
216-
msaaTextureDescriptorGPU.sampleCount = sampleCount;
212+
msaaTextureDescriptorGPU.sampleCount = samples;
217213

218214
textureData.msaaTexture = backend.device.createTexture( msaaTextureDescriptorGPU );
219215

@@ -336,7 +332,7 @@ class WebGPUTextureUtils {
336332
depthTexture.image.width = width;
337333
depthTexture.image.height = height;
338334

339-
this.createTexture( depthTexture, { sampleCount: backend.utils.getSampleCount( backend.renderer.samples ), width, height } );
335+
this.createTexture( depthTexture, { width, height } );
340336

341337
return backend.get( depthTexture ).texture;
342338

src/renderers/webgpu/utils/WebGPUUtils.js

+30
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,36 @@ class WebGPUUtils {
3636

3737
}
3838

39+
getTextureSampleData( texture ) {
40+
41+
let samples;
42+
43+
if ( texture.isFramebufferTexture ) {
44+
45+
samples = 1;
46+
47+
} else if ( texture.isDepthTexture && ! texture.renderTarget ) {
48+
49+
const renderer = this.backend.renderer;
50+
const renderTarget = renderer.getRenderTarget();
51+
52+
samples = renderTarget ? renderTarget.samples : renderer.samples;
53+
54+
} else if ( texture.renderTarget ) {
55+
56+
samples = texture.renderTarget.samples;
57+
58+
}
59+
60+
samples = samples || 1;
61+
62+
const isMSAA = samples > 1 && texture.renderTarget !== null && ( texture.isDepthTexture !== true && texture.isFramebufferTexture !== true );
63+
const primarySamples = isMSAA ? 1 : samples;
64+
65+
return { samples, primarySamples, isMSAA };
66+
67+
}
68+
3969
getCurrentColorFormat( renderContext ) {
4070

4171
let format;

src/textures/Texture.js

+4
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class Texture extends EventDispatcher {
6969
this.version = 0;
7070
this.onUpdate = null;
7171

72+
this.renderTarget = null; // assign texture to a render target
7273
this.isRenderTargetTexture = false; // indicates whether a texture belongs to a render target or not
7374
this.pmremVersion = 0; // indicates whether this texture should be processed by PMREMGenerator or not (only relevant for render target textures)
7475

@@ -134,6 +135,9 @@ class Texture extends EventDispatcher {
134135
this.unpackAlignment = source.unpackAlignment;
135136
this.colorSpace = source.colorSpace;
136137

138+
this.renderTarget = source.renderTarget;
139+
this.isRenderTargetTexture = source.isRenderTargetTexture;
140+
137141
this.userData = JSON.parse( JSON.stringify( source.userData ) );
138142

139143
this.needsUpdate = true;

0 commit comments

Comments
 (0)