Skip to content

Commit 75d9699

Browse files
authored
WGSLNodeBuilder: Fix pow() with negative base on Windows (#28971)
* WGSLNodeBuilder: Fix pow() with negative base on Windows * restore tsl galaxy example * Update webgpu_tsl_galaxy.jpg * puppeteer: add webgpu_tsl_galaxy
1 parent f8a6f72 commit 75d9699

File tree

4 files changed

+38
-34
lines changed

4 files changed

+38
-34
lines changed
-7.05 KB
Loading

examples/webgpu_tsl_galaxy.html

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
<script type="module">
2828

2929
import * as THREE from 'three';
30-
import { color, cos, float, mix, range, sin, timerLocal, uniform, uv, vec3, vec4, PI, PI2, tslFn } from 'three/tsl';
30+
import { color, cos, float, mix, range, sin, timerLocal, uniform, uv, vec3, vec4, PI2 } from 'three/tsl';
3131

3232
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
3333
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
@@ -70,22 +70,7 @@
7070
sin( angle )
7171
).mul( radius );
7272

73-
const sphericalToVec3 = tslFn( ( [ phi, theta ] ) => {
74-
75-
const sinPhiRadius = sin( phi );
76-
77-
return vec3(
78-
sinPhiRadius.mul( sin( theta ) ),
79-
cos( phi ),
80-
sinPhiRadius.mul( cos( theta ) )
81-
);
82-
83-
} );
84-
85-
const phi = range( 0, PI2 );
86-
const theta = range( 0, PI );
87-
const offsetRadius = range( 0, 1 ).pow( 2 ).mul( radiusRatio ).mul( 1.25 );
88-
const randomOffset = sphericalToVec3( phi, theta ).mul( offsetRadius );
73+
const randomOffset = range( vec3( - 1 ), vec3( 1 ) ).pow( 3 ).mul( radiusRatio ).add( 0.2 );
8974

9075
material.positionNode = position.add( randomOffset );
9176

src/renderers/webgpu/nodes/WGSLNodeBuilder.js

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -72,23 +72,6 @@ const wgslTypeLib = {
7272
bmat4: 'mat4x4<bool>'
7373
};
7474

75-
const wgslMethods = {
76-
dFdx: 'dpdx',
77-
dFdy: '- dpdy',
78-
mod_float: 'threejs_mod_float',
79-
mod_vec2: 'threejs_mod_vec2',
80-
mod_vec3: 'threejs_mod_vec3',
81-
mod_vec4: 'threejs_mod_vec4',
82-
equals_bool: 'threejs_equals_bool',
83-
equals_bvec2: 'threejs_equals_bvec2',
84-
equals_bvec3: 'threejs_equals_bvec3',
85-
equals_bvec4: 'threejs_equals_bvec4',
86-
lessThanEqual: 'threejs_lessThanEqual',
87-
greaterThan: 'threejs_greaterThan',
88-
inversesqrt: 'inverseSqrt',
89-
bitcast: 'bitcast<f32>'
90-
};
91-
9275
const wgslPolyfill = {
9376
threejs_xor: new CodeNode( `
9477
fn threejs_xor( a : bool, b : bool ) -> bool {
@@ -153,6 +136,41 @@ fn threejs_biquadraticTexture( map : texture_2d<f32>, coord : vec2f, level : i32
153136
` )
154137
};
155138

139+
const wgslMethods = {
140+
dFdx: 'dpdx',
141+
dFdy: '- dpdy',
142+
mod_float: 'threejs_mod_float',
143+
mod_vec2: 'threejs_mod_vec2',
144+
mod_vec3: 'threejs_mod_vec3',
145+
mod_vec4: 'threejs_mod_vec4',
146+
equals_bool: 'threejs_equals_bool',
147+
equals_bvec2: 'threejs_equals_bvec2',
148+
equals_bvec3: 'threejs_equals_bvec3',
149+
equals_bvec4: 'threejs_equals_bvec4',
150+
lessThanEqual: 'threejs_lessThanEqual',
151+
greaterThan: 'threejs_greaterThan',
152+
inversesqrt: 'inverseSqrt',
153+
bitcast: 'bitcast<f32>'
154+
};
155+
156+
// WebGPU issue: does not support pow() with negative base on Windows
157+
158+
if ( /Windows/g.test( navigator.userAgent ) ) {
159+
160+
wgslPolyfill.pow_float = new CodeNode( 'fn threejs_pow_float( a : f32, b : f32 ) -> f32 { return select( -pow( -a, b ), pow( a, b ), a > 0.0 ); }' );
161+
wgslPolyfill.pow_vec2 = new CodeNode( 'fn threejs_pow_vec2( a : vec2f, b : vec2f ) -> vec2f { return vec2f( threejs_pow_float( a.x, b.x ), threejs_pow_float( a.y, b.y ) ); }', [ wgslPolyfill.pow_float ] );
162+
wgslPolyfill.pow_vec3 = new CodeNode( 'fn threejs_pow_vec3( a : vec3f, b : vec3f ) -> vec3f { return vec3f( threejs_pow_float( a.x, b.x ), threejs_pow_float( a.y, b.y ), threejs_pow_float( a.z, b.z ) ); }', [ wgslPolyfill.pow_float ] );
163+
wgslPolyfill.pow_vec4 = new CodeNode( 'fn threejs_pow_vec4( a : vec4f, b : vec4f ) -> vec4f { return vec4f( threejs_pow_float( a.x, b.x ), threejs_pow_float( a.y, b.y ), threejs_pow_float( a.z, b.z ), threejs_pow_float( a.w, b.w ) ); }', [ wgslPolyfill.pow_float ] );
164+
165+
wgslMethods.pow_float = 'threejs_pow_float';
166+
wgslMethods.pow_vec2 = 'threejs_pow_vec2';
167+
wgslMethods.pow_vec3 = 'threejs_pow_vec3';
168+
wgslMethods.pow_vec4 = 'threejs_pow_vec4';
169+
170+
}
171+
172+
//
173+
156174
class WGSLNodeBuilder extends NodeBuilder {
157175

158176
constructor( object, renderer ) {

test/e2e/puppeteer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ const exceptionList = [
150150
'webgpu_performance_renderbundle',
151151
'webgpu_lights_rectarealight',
152152
'webgpu_tsl_vfx_flames',
153+
'webgpu_tsl_galaxy',
153154

154155
// WebGPU idleTime and parseTime too low
155156
'webgpu_compute_particles',

0 commit comments

Comments
 (0)