|
|
 |
WebGPU Shader Language...
Even web-pages can use the power of the GPU... |
|
|
|
 | WGSL '%' vs GLSL 'mod' |  |
Are they the same?
NO
In GLSL, the `mod(x, y)` function computes true mathematical modulo, which always returns a non-negative result in the range [0, y) , even when x is negative. This is useful for periodic operations like wrapping angles or texture coordinates. However, WGSL's % operator is a remainder operation, not a true modulo—it preserves the sign of the dividend (x % y has the same sign as x ). This means negative inputs can produce negative results, which can cause issues in polar coordinate calculations, tiling, or other cases where a positive range is expected.
To match GLSL's mod behavior in WGSL, we need to manually adjust the result. A common approach is to compute x - y * floor(x / y) , which ensures the output stays non-negative. Below is a mymod(..) function that replicates GLSL's mod in WGSL, followed by a simple example demonstrating the difference between WGSL's % and the corrected version.
 | Example: mymod vs % in WGSL |  |
// Replicates GLSL's mod(x, y) behavior
fn mymod(x: f32, y: f32) -> f32 {
return x - y * floor(x / y);
}
@fragment
fn main(@builtin(position) fragCoord: vec4<f32>) -> @location(0) vec4<f32> {
let x = -5.7;
let y = 3.0;
// WGSL '%' (remainder, keeps sign)
let wgsl_mod = x % y; // Returns -2.7
// GLSL-style mod (always positive)
let glsl_mod = mymod(x, y); // Returns 0.3 (same as GLSL)
// Visualize the difference
if (fragCoord.x < 300.0) {
return vec4<f32>(wgsl_mod, 0.0, 0.0, 1.0); // Red if negative
} else {
return vec4<f32>(0.0, glsl_mod, 0.0, 1.0); // Green if positive
}
}
This example shows that -5.7 % 3.0 in WGSL gives -2.7 (remainder), while mymod(-5.7, 3.0) correctly returns 0.3 (like GLSL). Use mymod when you need periodic wrapping without negative results.
|
|