Skip to content

Commit 97244a7

Browse files
WGSLNodeBuilder: Fix array texture layer support for filtered sampling (mrdoob#32990)
1 parent 461515f commit 97244a7

1 file changed

Lines changed: 109 additions & 22 deletions

File tree

src/renderers/webgpu/nodes/WGSLNodeBuilder.js

Lines changed: 109 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,29 @@ fn tsl_biquadraticTexture( map : texture_2d<f32>, coord : vec2f, iRes : vec2u, l
112112
113113
return mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y );
114114
115+
}
116+
` ),
117+
biquadraticTextureArray: new CodeNode( /* wgsl */`
118+
fn tsl_biquadraticTexture_array( map : texture_2d_array<f32>, coord : vec2f, iRes : vec2u, layer : u32, level : u32 ) -> vec4f {
119+
120+
let res = vec2f( iRes );
121+
122+
let uvScaled = coord * res;
123+
let uvWrapping = ( ( uvScaled % res ) + res ) % res;
124+
125+
// https://www.shadertoy.com/view/WtyXRy
126+
127+
let uv = uvWrapping - 0.5;
128+
let iuv = floor( uv );
129+
let f = fract( uv );
130+
131+
let rg1 = textureLoad( map, vec2u( iuv + vec2( 0.5, 0.5 ) ) % iRes, layer, level );
132+
let rg2 = textureLoad( map, vec2u( iuv + vec2( 1.5, 0.5 ) ) % iRes, layer, level );
133+
let rg3 = textureLoad( map, vec2u( iuv + vec2( 0.5, 1.5 ) ) % iRes, layer, level );
134+
let rg4 = textureLoad( map, vec2u( iuv + vec2( 1.5, 1.5 ) ) % iRes, layer, level );
135+
136+
return mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y );
137+
115138
}
116139
` )
117140
};
@@ -271,17 +294,31 @@ class WGSLNodeBuilder extends NodeBuilder {
271294

272295
if ( this.isUnfilterable( texture ) === false ) {
273296

274-
if ( offsetSnippet ) {
297+
if ( depthSnippet ) {
275298

276-
return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;
299+
if ( offsetSnippet ) {
277300

278-
}
301+
return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;
302+
303+
}
304+
305+
return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ levelSnippet } )`;
279306

280-
return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet } )`;
307+
} else {
308+
309+
if ( offsetSnippet ) {
310+
311+
return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;
312+
313+
}
314+
315+
return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet } )`;
316+
317+
}
281318

282319
} else if ( this.isFilteredTexture( texture ) ) {
283320

284-
return this.generateFilteredTexture( texture, textureProperty, uvSnippet, offsetSnippet, levelSnippet );
321+
return this.generateFilteredTexture( texture, textureProperty, uvSnippet, offsetSnippet, levelSnippet, depthSnippet );
285322

286323
} else {
287324

@@ -465,11 +502,10 @@ class WGSLNodeBuilder extends NodeBuilder {
465502
* @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
466503
* @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
467504
* @param {string} [levelSnippet='0u'] - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
505+
* @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
468506
* @return {string} The WGSL snippet.
469507
*/
470-
generateFilteredTexture( texture, textureProperty, uvSnippet, offsetSnippet, levelSnippet = '0u' ) {
471-
472-
this._include( 'biquadraticTexture' );
508+
generateFilteredTexture( texture, textureProperty, uvSnippet, offsetSnippet, levelSnippet = '0u', depthSnippet ) {
473509

474510
const wrapFunction = this.generateWrapFunction( texture );
475511
const textureDimension = this.generateTextureDimension( texture, textureProperty, levelSnippet );
@@ -480,6 +516,16 @@ class WGSLNodeBuilder extends NodeBuilder {
480516

481517
}
482518

519+
if ( depthSnippet ) {
520+
521+
this._include( 'biquadraticTextureArray' );
522+
523+
return `tsl_biquadraticTexture_array( ${ textureProperty }, ${ wrapFunction }( ${ uvSnippet } ), ${ textureDimension }, u32( ${ depthSnippet } ), u32( ${ levelSnippet } ) )`;
524+
525+
}
526+
527+
this._include( 'biquadraticTexture' );
528+
483529
return `tsl_biquadraticTexture( ${ textureProperty }, ${ wrapFunction }( ${ uvSnippet } ), ${ textureDimension }, u32( ${ levelSnippet } ) )`;
484530

485531
}
@@ -698,14 +744,27 @@ class WGSLNodeBuilder extends NodeBuilder {
698744

699745
if ( shaderStage === 'fragment' ) {
700746

701-
// TODO handle i32 or u32 --> uvSnippet, array_index: A, ddx, ddy
702-
if ( offsetSnippet ) {
747+
if ( depthSnippet ) {
703748

704-
return `textureSampleGrad( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] }, ${ offsetSnippet } )`;
749+
if ( offsetSnippet ) {
705750

706-
}
751+
return `textureSampleGrad( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] }, ${ offsetSnippet } )`;
752+
753+
}
754+
755+
return `textureSampleGrad( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] } )`;
756+
757+
} else {
707758

708-
return `textureSampleGrad( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] } )`;
759+
if ( offsetSnippet ) {
760+
761+
return `textureSampleGrad( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] }, ${ offsetSnippet } )`;
762+
763+
}
764+
765+
return `textureSampleGrad( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ gradSnippet[ 0 ] }, ${ gradSnippet[ 1 ] } )`;
766+
767+
}
709768

710769
} else {
711770

@@ -776,17 +835,31 @@ class WGSLNodeBuilder extends NodeBuilder {
776835

777836
if ( this.isUnfilterable( texture ) === false ) {
778837

779-
if ( offsetSnippet ) {
838+
if ( depthSnippet ) {
780839

781-
return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;
840+
if ( offsetSnippet ) {
782841

783-
}
842+
return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;
784843

785-
return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet } )`;
844+
}
845+
846+
return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ levelSnippet } )`;
847+
848+
} else {
849+
850+
if ( offsetSnippet ) {
851+
852+
return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet }, ${ offsetSnippet } )`;
853+
854+
}
855+
856+
return `textureSampleLevel( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ levelSnippet } )`;
857+
858+
}
786859

787860
} else if ( this.isFilteredTexture( texture ) ) {
788861

789-
return this.generateFilteredTexture( texture, textureProperty, uvSnippet, offsetSnippet, levelSnippet );
862+
return this.generateFilteredTexture( texture, textureProperty, uvSnippet, offsetSnippet, levelSnippet, depthSnippet );
790863

791864
} else {
792865

@@ -812,13 +885,27 @@ class WGSLNodeBuilder extends NodeBuilder {
812885

813886
if ( shaderStage === 'fragment' ) {
814887

815-
if ( offsetSnippet ) {
888+
if ( depthSnippet ) {
816889

817-
return `textureSampleBias( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ biasSnippet }, ${ offsetSnippet } )`;
890+
if ( offsetSnippet ) {
818891

819-
}
892+
return `textureSampleBias( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ biasSnippet }, ${ offsetSnippet } )`;
893+
894+
}
895+
896+
return `textureSampleBias( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ depthSnippet }, ${ biasSnippet } )`;
897+
898+
} else {
899+
900+
if ( offsetSnippet ) {
820901

821-
return `textureSampleBias( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ biasSnippet } )`;
902+
return `textureSampleBias( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ biasSnippet }, ${ offsetSnippet } )`;
903+
904+
}
905+
906+
return `textureSampleBias( ${ textureProperty }, ${ textureProperty }_sampler, ${ uvSnippet }, ${ biasSnippet } )`;
907+
908+
}
822909

823910
} else {
824911

0 commit comments

Comments
 (0)