Skip to content

Multiplicative operator precedence in TSL Transpiler #31513

@shotamatsuda

Description

@shotamatsuda

Description

Related issue: #28586

Since the multiplicative operators (* and /) have the same precedence order and left-to-right associativity in GLSL, WGSL, and other programming languages, a / b * (c / d) must be evaluated as (a / b) * (c / d), but the TSL Transpiler evaluates it as a / (b * (c / d)).

Input expression to TSL transpiler:

float r = a / b * (c / d);

Output using TSL encoder:

const r = a.div( b.mul( c.div( d ) ) );

Expected:

const r = a.div( b ).mul( c.div( d ) );

Output using WGSL encoder:

let r: f32 = a / ( b * ( c / d ) );

Expected:

let r: f32 = a / b * ( c / d );

Reproduction steps

  1. Open the WebGPU TSL Transpiler
  2. Enter the following code in the left panel: float r = a / b * (c / d);
  3. The right panel shows: const r = a.div( b.mul( c.div( d ) ) );

Code

import GLSLDecoder from 'three/addons/transpiler/GLSLDecoder.js'
import Transpiler from 'three/addons/transpiler/Transpiler.js'
import TSLEncoder from 'three/addons/transpiler/TSLEncoder.js'
import WGSLEncoder from 'three/addons/transpiler/WGSLEncoder.js'

const glsl = 'float r = a / b * (c / d);'
const decoder = new GLSLDecoder()
const tslEncoder = new TSLEncoder()
const wgslEncoder = new WGSLEncoder()

console.log(new Transpiler(decoder, tslEncoder).parse(glsl)) // Outputs: const r = a.div( b.mul( c.div( d ) ) );
console.log(new Transpiler(decoder, wgslEncoder).parse(glsl)) // Outputs: let r: f32 = a / ( b * ( c / d ) );

Live example

https://codepen.io/shotamatsuda/pen/dPYpdxj

Screenshots

Version

r178

Device

Desktop

Browser

Chrome

OS

MacOS

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugTSLThree.js Shading Language

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions