Skip to content

Commit c959ad2

Browse files
committed
std.not mimics WGSL
1 parent 3d768c7 commit c959ad2

File tree

3 files changed

+15
-2
lines changed

3 files changed

+15
-2
lines changed

packages/typegpu/src/std/boolean.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ function cpuNot(value: number): boolean;
180180
function cpuNot<T extends AnyVecInstance>(value: T): VecInstanceToBooleanVecInstance<T>;
181181
function cpuNot(value: unknown): boolean;
182182
function cpuNot(value: unknown): boolean | AnyBooleanVecInstance {
183+
if (typeof value === 'number' && isNaN(value)) {
184+
return false;
185+
}
186+
183187
if (isVecInstance(value)) {
184188
if (value.length === 2) {
185189
return vec2b(!value.x, !value.y);
@@ -206,6 +210,7 @@ function cpuNot(value: unknown): boolean | AnyBooleanVecInstance {
206210
* not(vec3b(true, true, false)) // returns vec3b(false, false, true)
207211
* not(vec3f(1.0, 0.0, -1.0)) // returns vec3b(false, true, false)
208212
* not({a: 1882}) // returns false
213+
* not(NaN) // returns false **as in WGSL**
209214
*/
210215
export const not = dualImpl({
211216
name: 'not',
@@ -217,8 +222,11 @@ export const not = dualImpl({
217222
};
218223
},
219224
normalImpl: cpuNot,
220-
codegenImpl: (ctx, [arg]) => {
225+
codegenImpl: (_ctx, [arg]) => {
221226
if (isKnownAtComptime(arg)) {
227+
if (typeof arg.value === 'number' && isNaN(arg.value)) {
228+
return 'false';
229+
}
222230
return `${!arg.value}`;
223231
}
224232

packages/typegpu/src/tgsl/wgslGenerator.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ const unaryOpCodeToCodegen = {
173173
return snip(`!${argStr}`, bool, 'runtime');
174174
}
175175
if (wgsl.isNumericSchema(dataType)) {
176-
return snip(`!bool(${argStr})`, bool, 'runtime');
176+
// no bool cast, because bool(NaN) is true in WGSL but in JS it's false
177+
return snip(`!(${argStr} != 0)`, bool, 'runtime');
177178
}
178179

179180
return snip(false, bool, 'constant');

packages/typegpu/tests/std/boolean/not.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ describe('not', () => {
3636
expect(not(s)).toBe(false);
3737
});
3838

39+
it('mimics WGSL behavior on NaN', () => {
40+
expect(not(NaN)).toBe(false);
41+
});
42+
3943
it('generates correct WGSL on a boolean runtime-known argument', () => {
4044
const testFn = tgpu.fn(
4145
[d.bool],

0 commit comments

Comments
 (0)