diff --git a/examples/jsm/renderers/webgpu/nodes/WGSLNodeFunction.js b/examples/jsm/renderers/webgpu/nodes/WGSLNodeFunction.js index 1021eb6dc3037d..c0386beb84efce 100644 --- a/examples/jsm/renderers/webgpu/nodes/WGSLNodeFunction.js +++ b/examples/jsm/renderers/webgpu/nodes/WGSLNodeFunction.js @@ -2,10 +2,43 @@ import NodeFunction from '../../../nodes/core/NodeFunction.js'; import NodeFunctionInput from '../../../nodes/core/NodeFunctionInput.js'; const declarationRegexp = /^[fn]*\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)\s*[\-\>]*\s*([a-z_0-9]+)?/i; -const propertiesRegexp = /[a-z_0-9]+|<(.*?)>+/ig; +const propertiesRegexp = /([a-z_0-9]+)\s*:\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/ig; const wgslTypeLib = { - f32: 'float' + 'f32': 'float', + 'i32': 'int', + 'u32': 'uint', + 'bool': 'bool', + + 'vec2': 'vec2', + 'vec2': 'ivec2', + 'vec2': 'uvec2', + 'vec2': 'bvec2', + + 'vec3': 'vec3', + 'vec3': 'ivec3', + 'vec3': 'uvec3', + 'vec3': 'bvec3', + + 'vec4': 'vec4', + 'vec4': 'ivec4', + 'vec4': 'uvec4', + 'vec4': 'bvec4', + + 'mat2x2': 'mat2', + 'mat2x2': 'imat2', + 'mat2x2': 'umat2', + 'mat2x2': 'bmat2', + + 'mat3x3': 'mat3', + 'mat3x3': 'imat3', + 'mat3x3': 'umat3', + 'mat3x3': 'bmat3', + + 'mat4x4': 'mat4', + 'mat4x4': 'imat4', + 'mat4x4': 'umat4', + 'mat4x4': 'bmat4' }; const parse = ( source ) => { @@ -16,47 +49,36 @@ const parse = ( source ) => { if ( declaration !== null && declaration.length === 4 ) { - // tokenizer - const inputsCode = declaration[ 2 ]; const propsMatches = []; + let match = null; - let nameMatch = null; - - while ( ( nameMatch = propertiesRegexp.exec( inputsCode ) ) !== null ) { + while ( ( match = propertiesRegexp.exec( inputsCode ) ) !== null ) { - propsMatches.push( nameMatch ); + propsMatches.push( { name: match[ 1 ], type: match[ 2 ] } ); } - // parser - + // Process matches to correctly pair names and types const inputs = []; + for ( let i = 0; i < propsMatches.length; i ++ ) { - let i = 0; + const { name, type } = propsMatches[ i ]; - while ( i < propsMatches.length ) { + let resolvedType = type; - // default + if ( resolvedType.startsWith( 'texture' ) ) { - const name = propsMatches[ i ++ ][ 0 ]; - let type = propsMatches[ i ++ ][ 0 ]; + resolvedType = type.split( '<' )[ 0 ]; - type = wgslTypeLib[ type ] || type; + } - // precision + resolvedType = wgslTypeLib[ resolvedType ] || resolvedType; - if ( i < propsMatches.length && propsMatches[ i ][ 0 ].startsWith( '<' ) === true ) - i ++; - - // add input - - inputs.push( new NodeFunctionInput( type, name ) ); + inputs.push( new NodeFunctionInput( resolvedType, name ) ); } - // - const blockCode = source.substring( declaration[ 0 ].length ); const name = declaration[ 1 ] !== undefined ? declaration[ 1 ] : ''; diff --git a/examples/webgpu_tsl_interoperability.html b/examples/webgpu_tsl_interoperability.html index cbf958b3e7cdb3..196e5be6a059a8 100644 --- a/examples/webgpu_tsl_interoperability.html +++ b/examples/webgpu_tsl_interoperability.html @@ -32,7 +32,7 @@ import WebGL from 'three/addons/capabilities/WebGL.js'; import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js'; - import { tslFn, attribute, varyingProperty, timerLocal, uniform, wgslFn, texture, uv, clamp, float, vec2, vec3, fract, floor, MeshBasicNodeMaterial, positionGeometry, sin } from 'three/nodes'; + import { tslFn, sampler, attribute, varyingProperty, timerLocal, uniform, wgslFn, texture, uv, clamp, float, vec2, vec3, fract, floor, MeshBasicNodeMaterial, positionGeometry, sin } from 'three/nodes'; import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; @@ -109,12 +109,12 @@ crtHeight ); // Coordinate for each cell in the pixel map - var coord = pixel / cellSize; + let coord = pixel / cellSize; // Three color values for each cell (r, g, b) - var subcoord = coord * vec2f( 3.0, 1.0 ); - var offset = vec2( 0, fract( floor( coord.x ) * cellOffset ) ); + let subcoord = coord * vec2f( 3.0, 1.0 ); + let offset = vec2( 0, fract( floor( coord.x ) * cellOffset ) ); - var maskCoord = floor( coord + offset ) * cellSize; + let maskCoord = floor( coord + offset ) * cellSize; var samplePoint = maskCoord / vec2(crtWidth, crtHeight); samplePoint.x += fract( time * speed / 20 ); @@ -127,7 +127,7 @@ // Current implementation does not give an even amount of space to each r, g, b unit of a cell // Fix/hack this by multiplying subCoord.x by cellSize at cellSizes below 6 - var ind = floor( subcoord.x ) % 3; + let ind = floor( subcoord.x ) % 3; var maskColor = vec3( f32( ind == 0.0 ), @@ -135,7 +135,7 @@ f32( ind == 2.0 ) ) * 3.0; - var cellUV = fract( subcoord + offset ) * 2.0 - 1.0; + let cellUV = fract( subcoord + offset ) * 2.0 - 1.0; var border: vec2 = 1.0 - cellUV * cellUV * borderMask; maskColor *= vec3f( clamp( border.x, 0.0, 1.0 ) * clamp( border.y, 0.0, 1.0) ); @@ -180,7 +180,7 @@ wgslShaderMaterial.fragmentNode = wgslFragmentShader( { vUv: vUv, tex: texture( planetTexture ), - texSampler: texture( planetTexture ), + texSampler: sampler( planetTexture ), crtWidth: crtWidthUniform, crtHeight: crtHeightUniform, cellOffset: cellOffsetUniform,