Skip to content

Commit 9f289d8

Browse files
authored
WGSLNodeBuilder: Improve NearestFilter support (mrdoob#29910)
1 parent d792454 commit 9f289d8

File tree

1 file changed

+43
-29
lines changed

1 file changed

+43
-29
lines changed

src/renderers/webgpu/nodes/WGSLNodeBuilder.js

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ import { getFormat } from '../utils/WebGPUTextureUtils.js';
1313
import WGSLNodeParser from './WGSLNodeParser.js';
1414
import { GPUBufferBindingType, GPUStorageTextureAccess } from '../utils/WebGPUConstants.js';
1515

16-
import { NoColorSpace, FloatType, RepeatWrapping, ClampToEdgeWrapping, MirroredRepeatWrapping } from '../../../constants.js';
16+
import VarNode from '../../../nodes/core/VarNode.js';
17+
import ExpressionNode from '../../../nodes/code/ExpressionNode.js';
18+
19+
import { NoColorSpace, FloatType, RepeatWrapping, ClampToEdgeWrapping, MirroredRepeatWrapping, NearestFilter } from '../../../constants.js';
1720

1821
// GPUShaderStage is not defined in browsers not supporting WebGPU
1922
const GPUShaderStage = self.GPUShaderStage;
@@ -82,17 +85,8 @@ const wgslPolyfill = {
8285
repeatWrapping_float: new CodeNode( 'fn tsl_repeatWrapping_float( coord: f32 ) -> f32 { return fract( coord ); }' ),
8386
mirrorWrapping_float: new CodeNode( 'fn tsl_mirrorWrapping_float( coord: f32 ) -> f32 { let mirrored = fract( coord * 0.5 ) * 2.0; return 1.0 - abs( 1.0 - mirrored ); }' ),
8487
clampWrapping_float: new CodeNode( 'fn tsl_clampWrapping_float( coord: f32 ) -> f32 { return clamp( coord, 0.0, 1.0 ); }' ),
85-
repeatWrapping: new CodeNode( /* wgsl */`
86-
fn tsl_repeatWrapping( uv : vec2<f32>, dimension : vec2<u32> ) -> vec2<u32> {
87-
88-
let uvScaled = vec2<u32>( uv * vec2<f32>( dimension ) );
89-
90-
return ( ( uvScaled % dimension ) + dimension ) % dimension;
91-
92-
}
93-
` ),
9488
biquadraticTexture: new CodeNode( /* wgsl */`
95-
fn tsl_biquadraticTexture( map : texture_2d<f32>, coord : vec2f, iRes : vec2u, level : i32 ) -> vec4f {
89+
fn tsl_biquadraticTexture( map : texture_2d<f32>, coord : vec2f, iRes : vec2u, level : u32 ) -> vec4f {
9690
9791
let res = vec2f( iRes );
9892
@@ -201,7 +195,7 @@ class WGSLNodeBuilder extends NodeBuilder {
201195

202196
} else {
203197

204-
return this.generateTextureLod( texture, textureProperty, uvSnippet, '0' );
198+
return this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, '0' );
205199

206200
}
207201

@@ -233,7 +227,7 @@ class WGSLNodeBuilder extends NodeBuilder {
233227

234228
} else {
235229

236-
return this.generateTextureLod( texture, textureProperty, uvSnippet, levelSnippet );
230+
return this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, levelSnippet );
237231

238232
}
239233

@@ -305,52 +299,63 @@ class WGSLNodeBuilder extends NodeBuilder {
305299

306300
if ( textureData.dimensionsSnippet === undefined ) textureData.dimensionsSnippet = {};
307301

308-
let propertyName = textureData.dimensionsSnippet[ levelSnippet ];
302+
let textureDimensionNode = textureData.dimensionsSnippet[ levelSnippet ];
309303

310304
if ( textureData.dimensionsSnippet[ levelSnippet ] === undefined ) {
311305

312-
propertyName = `textureDimension_${ texture.id }_${ levelSnippet }`;
306+
let textureDimensionsParams;
307+
308+
if ( texture.isMultisampleRenderTargetTexture === true ) {
309+
310+
textureDimensionsParams = textureProperty;
311+
312+
} else {
313+
314+
textureDimensionsParams = `${ textureProperty }, u32( ${ levelSnippet } )`;
315+
316+
}
313317

314-
this.addLineFlowCode( `let ${ propertyName } = textureDimensions( ${ textureProperty }, i32( ${ levelSnippet } ) );` );
318+
textureDimensionNode = new VarNode( new ExpressionNode( `textureDimensions( ${ textureDimensionsParams } )`, 'uvec2' ) );
315319

316-
textureData.dimensionsSnippet[ levelSnippet ] = propertyName;
320+
textureData.dimensionsSnippet[ levelSnippet ] = textureDimensionNode;
317321

318322
}
319323

320-
return propertyName;
324+
return textureDimensionNode.build( this );
321325

322326
}
323327

324-
generateFilteredTexture( texture, textureProperty, uvSnippet, levelSnippet = '0' ) {
328+
generateFilteredTexture( texture, textureProperty, uvSnippet, levelSnippet = '0u' ) {
325329

326330
this._include( 'biquadraticTexture' );
327331

328332
const wrapFunction = this.generateWrapFunction( texture );
329333
const textureDimension = this.generateTextureDimension( texture, textureProperty, levelSnippet );
330334

331-
return `tsl_biquadraticTexture( ${ textureProperty }, ${ wrapFunction }( ${ uvSnippet } ), ${ textureDimension }, i32( ${ levelSnippet } ) )`;
335+
return `tsl_biquadraticTexture( ${ textureProperty }, ${ wrapFunction }( ${ uvSnippet } ), ${ textureDimension }, u32( ${ levelSnippet } ) )`;
332336

333337
}
334338

335-
generateTextureLod( texture, textureProperty, uvSnippet, levelSnippet = '0' ) {
339+
generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, levelSnippet = '0u' ) {
336340

337-
this._include( 'repeatWrapping' );
341+
const wrapFunction = this.generateWrapFunction( texture );
342+
const textureDimension = this.generateTextureDimension( texture, textureProperty, levelSnippet );
338343

339-
const dimension = texture.isMultisampleRenderTargetTexture === true ? `textureDimensions( ${ textureProperty } )` : `textureDimensions( ${ textureProperty }, 0 )`;
344+
const coordSnippet = `vec2u( ${ wrapFunction }( ${ uvSnippet } ) * vec2f( ${ textureDimension } ) )`;
340345

341-
return `textureLoad( ${ textureProperty }, tsl_repeatWrapping( ${ uvSnippet }, ${ dimension } ), i32( ${ levelSnippet } ) )`;
346+
return this.generateTextureLoad( texture, textureProperty, coordSnippet, depthSnippet, levelSnippet );
342347

343348
}
344349

345350
generateTextureLoad( texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0u' ) {
346351

347352
if ( depthSnippet ) {
348353

349-
return `textureLoad( ${ textureProperty }, ${ uvIndexSnippet }, ${ depthSnippet }, ${ levelSnippet } )`;
354+
return `textureLoad( ${ textureProperty }, ${ uvIndexSnippet }, ${ depthSnippet }, u32( ${ levelSnippet } ) )`;
350355

351356
} else {
352357

353-
return `textureLoad( ${ textureProperty }, ${ uvIndexSnippet }, ${ levelSnippet } )`;
358+
return `textureLoad( ${ textureProperty }, ${ uvIndexSnippet }, u32( ${ levelSnippet } ) )`;
354359

355360
}
356361

@@ -362,9 +367,18 @@ class WGSLNodeBuilder extends NodeBuilder {
362367

363368
}
364369

370+
isSampleCompare( texture ) {
371+
372+
return texture.isDepthTexture === true && texture.compareFunction !== null;
373+
374+
}
375+
365376
isUnfilterable( texture ) {
366377

367-
return this.getComponentTypeFromTexture( texture ) !== 'float' || ( ! this.isAvailable( 'float32Filterable' ) && texture.isDataTexture === true && texture.type === FloatType ) || texture.isMultisampleRenderTargetTexture === true;
378+
return this.getComponentTypeFromTexture( texture ) !== 'float' ||
379+
( ! this.isAvailable( 'float32Filterable' ) && texture.isDataTexture === true && texture.type === FloatType ) ||
380+
( this.isSampleCompare( texture ) === false && texture.minFilter === NearestFilter && texture.magFilter === NearestFilter ) ||
381+
texture.isMultisampleRenderTargetTexture === true;
368382

369383
}
370384

@@ -378,7 +392,7 @@ class WGSLNodeBuilder extends NodeBuilder {
378392

379393
} else if ( this.isUnfilterable( texture ) ) {
380394

381-
snippet = this.generateTextureLod( texture, textureProperty, uvSnippet, '0', depthSnippet, shaderStage );
395+
snippet = this.generateTextureLod( texture, textureProperty, uvSnippet, depthSnippet, '0', shaderStage );
382396

383397
} else {
384398

@@ -1106,7 +1120,7 @@ ${ flowData.code }
11061120

11071121
if ( shaderStage === 'fragment' && this.isUnfilterable( texture ) === false && uniform.node.isStorageTextureNode !== true ) {
11081122

1109-
if ( texture.isDepthTexture === true && texture.compareFunction !== null ) {
1123+
if ( this.isSampleCompare( texture ) ) {
11101124

11111125
bindingSnippets.push( `@binding( ${ uniformIndexes.binding ++ } ) @group( ${ uniformIndexes.group } ) var ${ uniform.name }_sampler : sampler_comparison;` );
11121126

0 commit comments

Comments
 (0)