Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 47 additions & 25 deletions examples/jsm/renderers/webgpu/nodes/WGSLNodeFunction.js
Original file line number Diff line number Diff line change
Expand Up @@ -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<f32>': 'vec2',
'vec2<i32>': 'ivec2',
'vec2<u32>': 'uvec2',
'vec2<bool>': 'bvec2',

'vec3<f32>': 'vec3',
'vec3<i32>': 'ivec3',
'vec3<u32>': 'uvec3',
'vec3<bool>': 'bvec3',

'vec4<f32>': 'vec4',
'vec4<i32>': 'ivec4',
'vec4<u32>': 'uvec4',
'vec4<bool>': 'bvec4',

'mat2x2<f32>': 'mat2',
'mat2x2<i32>': 'imat2',
'mat2x2<u32>': 'umat2',
'mat2x2<bool>': 'bmat2',

'mat3x3<f32>': 'mat3',
'mat3x3<i32>': 'imat3',
'mat3x3<u32>': 'umat3',
'mat3x3<bool>': 'bmat3',

'mat4x4<f32>': 'mat4',
'mat4x4<i32>': 'imat4',
'mat4x4<u32>': 'umat4',
'mat4x4<bool>': 'bmat4'
};

const parse = ( source ) => {
Expand All @@ -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 ] : '';
Expand Down
16 changes: 8 additions & 8 deletions examples/webgpu_tsl_interoperability.html
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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<f32>( 0, fract( floor( coord.x ) * cellOffset ) );
let subcoord = coord * vec2f( 3.0, 1.0 );
let offset = vec2<f32>( 0, fract( floor( coord.x ) * cellOffset ) );

var maskCoord = floor( coord + offset ) * cellSize;
let maskCoord = floor( coord + offset ) * cellSize;

var samplePoint = maskCoord / vec2<f32>(crtWidth, crtHeight);
samplePoint.x += fract( time * speed / 20 );
Expand All @@ -127,15 +127,15 @@

// 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>(
f32( ind == 0.0 ),
f32( ind == 1.0 ),
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<f32> = 1.0 - cellUV * cellUV * borderMask;

maskColor *= vec3f( clamp( border.x, 0.0, 1.0 ) * clamp( border.y, 0.0, 1.0) );
Expand Down Expand Up @@ -180,7 +180,7 @@
wgslShaderMaterial.fragmentNode = wgslFragmentShader( {
vUv: vUv,
tex: texture( planetTexture ),
texSampler: texture( planetTexture ),
texSampler: sampler( planetTexture ),
crtWidth: crtWidthUniform,
crtHeight: crtHeightUniform,
cellOffset: cellOffsetUniform,
Expand Down