I'm seeing some strange behavior that I can't explain in a WebGL shader I've written. This is not an area of expertise for me, so it's entirely possible that I'm misunderstanding something pretty simple, but I'm not sure what.
I have a codepen illustrating the strange behavior here https://codepen.io/bjvanminnen/pen/XqMpvL.
void main () {
vec3 color = vec3(0.);
vec2 loc1 = vec2(0.5, 0.) / u_res;
vec2 loc2 = vec2(1.5, 0.) / u_res;
float val1 = texture2D(u_tex, loc1).r * 255.;
float val2 = texture2D(u_tex, loc1).r * 255.;
color.r = val1 == val2 ? 1. : 0.;
// commenting/uncommenting this line somehow affects the b value
// on iOS, when uncommented we end up with (53, 0, 255, 255)
// when commented we end up with (255, 0, 0, 255)
// I can think of no reason why the below line should affect color.b
color.r = floor(val1) / 255.;
color.b = val1 == 53. ? 1. : 0.;
gl_FragColor = vec4(color, 1.);
}
A summary of what's happening
In JS, I create a texture where each pixel is #350000
In my fragment shader, read the first two pixels
Initially set the r value of the output to be 1 if the two pixels are identical (they should be)
When uncommented, change the value of color.r based on the floor of val1 (a step that I would not expect to affect color.b)
Set the b value of the output to be 1 if the pixel value is 53 (i.e. 0x35).
I then examine the resulting pixel values in JS.
My expectations:
When the second color.r
line is commented out, I would expect a result of (53, 0, 255, 255). This IS what I see on my desktop, but on my iOS device I see (53, 0, 0, 255). It appears to be the case that val1 ends up being slightly larger than 53 on iOS. I'm assuming this is just floating point weirdness.
What's super strange and I can't understand is that when I comment out the second color.r
line, I get (255, 0, 255, 255) on my desktop - which makes sense - but (255, 0, 0, 255) on my iOS device.
In other words the presence/non-presence of the line color.r = floor(val1) / 255.;
is somehow changing the result of color.b
.
Have I encountered some strange iOS bug, or am I misunderstanding something here?
Looking in the GLSL ES 1.0 spec there's a bunch of sections on invariance starting at section 4.6
The important part for your case is probably 4.6.2
You're comparing a float to an exact value which seems dangerous in pretty much any language. If I change this line
to
Then it works as expected for me. Also, if I write out
val1
withI don't see it change. It's 88 whether or not that line is commented out even though your test fails. That suggests to me it's not 53.0 in one case. It's 53.000000000001 or 52.9999999999999 etc...