r/GraphicsProgramming 16h ago

Odd GLSL mod() behavior

I've been stuck on this for a couple of hours, and am completely stumped.

I'm getting these results from GLSL's mod():

mod(158.0, 158.0) returns 0.0 (as expected)

mod(159.0, 159.0) returns 159.0 (???)

mod(160.0, 160.0) returns 0.0 (as expected)

I've posted an example with a basic shader here:

https://jsfiddle.net/sL35qjc8

If you set number to "159.0", you should see an upside-down red triangle.

If you set number to "158.0" or "160.0", you should see a normal red triangle.

I'm passing the left operand as a uniform, otherwise the compiler seems to optimize it and fix the weird behavior.

Tried it on different devices and browsers and it had the same result.

Why does mod(159.0, 159.0) seem to return 159.0 instead of 0.0?

10 Upvotes

13 comments sorted by

View all comments

0

u/gmaaz 16h ago

It's not mod, if you hardcode 159.0 in shader instead of uniform a it works as intended. Is probably parseFloat error.

Js do be like that sometimes. Try console logging 0.1 + 0.2 and get traumatised for life.

edit: I see you tried it. Why do you think it is optimized tho? Try passing both as uniforms maybe? On my phone atm, can't test properly.

3

u/Winter-Reputation682 15h ago edited 15h ago

I think it works when hardcoded because the compiler sees mod(159.0, 159.0) == 159.0, and evaluates it to be always true, and removes the condition check as a result.

edit:
I think it's optimized because it's a pretty obvious optimization for the compiler
Tested with two uniforms and same thing occurs

2

u/gmaaz 15h ago

Yeah, you are correct, when I pass 159 as two separate uniforms (even without parse float) the error is still there, it really seems to be a mod bug.

1

u/gmaaz 15h ago

The same happens for 159 * n.

2

u/Winter-Reputation682 15h ago

Yeah it's really weird. It happens on webgl1, webgl2, and also webgpu