@@ -13,7 +13,10 @@ import { getFormat } from '../utils/WebGPUTextureUtils.js';
1313import WGSLNodeParser from './WGSLNodeParser.js' ;
1414import { 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
1922const 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