three.js icon indicating copy to clipboard operation
three.js copied to clipboard

TSL: Some names for a TSL function break the syntax of translated WGSL or GLSL code

Open boytchev opened this issue 1 year ago • 0 comments

Description

When a TSL code is translated into GLSL or WGSL some identifiers may break the code, because they collide with keywords or reserved words. For example, a TSL function named fn triggers the following error message:

Error while parsing WGSL: :17:4 error: expected identifier for function declaration
fn fn (  ) -> f32 {
   ^^

because fn is a keyword in WGSL.

Possible solutions:

  • Throw error or show warning when a keywords or reserved word is used – the (b)locked identifiers for GLSL and WGSL are different
  • Safeguard (all or only problematic) names by appending a prefix or suffix, e.g. fn may become fn_tsl
  • Add a warning in the documentation for users to avoid such identifiers
  • Leave it as it is

Reproduction steps

Example with WGSL:

  1. Open WebGPU TSL Editor and make sure the output in the right panel is set to WGSL
  2. Copy the following code in the left panel:
const { tslFn, vec4 } = TSL;

const fn = tslFn( () => { return 1; } );

fn.setLayout( {
	name: 'fn',
	type: 'float',
	inputs: []
} );

output = vec4( 1, 1, 1, fn() );
  1. Observe the translated code in the right panel. It contains:
// codes
fn fn (  ) -> f32 {
	return 1.0;
}
  1. Check the JS console. It shows error message
Error while parsing WGSL: :17:4 error: expected identifier for function declaration
fn fn (  ) -> f32 {
   ^^

:42:48 error: expected expression for function call
  output.color = vec4<f32>( 1.0, 1.0, 1.0, f32( fn(  ) ) );
                                                ^^


 - While validating [ShaderModuleDescriptor "fragment"]
 - While calling [Device].CreateShaderModule([ShaderModuleDescriptor "fragment"]).

Example with GLSL:

  1. Open WebGPU TSL Editor and make sure the output in the right panel is set to GLSL
  2. Copy the following code in the left panel:
const { tslFn, vec4 } = TSL;

const main = tslFn( () => { return 1; } );

main.setLayout( {
	name: 'main',
	type: 'float',
	inputs: []
} );

output = vec4( 1, 1, 1, main() );
  1. Observe the translated code in the right panel. It contains two definitions of main
  2. Check the JS console. It shows error message
Compilation log for [Invalid ShaderModule "fragment"]:
1 error(s) generated while compiling the shader:
:29:1 error: redeclaration of 'main'
fn main(  ) -> OutputStruct {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Code

See "Reproduction steps"

Live example

See "Reproduction steps"

Screenshots

image

Version

r165

Device

Desktop

Browser

Chrome

OS

Windows

boytchev avatar Jun 10 '24 10:06 boytchev