0
votes

I've been trying to work with WebGL and finally managed to find a 1-line change that can break one of the demos.

https://github.com/KhronosGroup/WebGL/blob/master/sdk/demos/webkit/SpiritBox.html

has a vertex shader :

uniform mat4 u_modelViewProjMatrix;
uniform mat4 u_normalMatrix;
uniform vec3 lightDir;

attribute vec3 vNormal;
attribute vec4 vTexCoord;
attribute vec4 vPosition;

varying float v_Dot;
varying vec2 v_texCoord;

void main()
{
    gl_Position = u_modelViewProjMatrix * vPosition;
    v_texCoord = vTexCoord.st;
    vec4 transNormal = u_normalMatrix * vec4(vNormal, 1);
    v_Dot = max(dot(transNormal.xyz, lightDir), 0.0);
}

The demo shows a spinning box with a picture of a puppy on each face.

If we add a single line to the end of the shader function:

    v_Dot = 1.0;

then the box now renders as white. Switching from =1.0 to

    v_Dot = max(v_Dot, 1.0);

makes the puppy reappear.

Here's a copy of the fragment shader just in case the link is broken:

precision mediump float;

uniform sampler2D sampler2d;

varying float v_Dot;
varying vec2 v_texCoord;

void main()
{
    vec2 texCoord = vec2(v_texCoord.s, 1.0 - v_texCoord.t);
    vec4 color = texture2D(sampler2d, texCoord);
    color += vec4(0.1, 0.1, 0.1, 1);
    gl_FragColor = vec4(color.xyz * v_Dot, color.a);
}

What the heck is going on here? I am using Firefox version 24.7.0 .

2
Please add the fragment shader to the question.Colonel Thirty Two
It could be a bug in the framework you are using. When you write v_Dot = 1.0;, the vNormal vertex attribute is no longer used, so the shader compiler will probably delete it from the program, and I've occasionally seen bugs in framework code that don't handle missing attributes / uniforms gracefully.Dietrich Epp

2 Answers

1
votes

Yes! I ran into exactly this bug, trying to add this exact same line to this exact same demo!

It is certainly a bug. Furthermore it manifests only on certain platforms. E.g. when I view the page on my macbook pro, it looks fine (spinning textured cube with bright non-directional lighting, as intended) but when I run it on my ubuntu box it fails (no texture, as you described). This is using chrome "Version 46.0.2490.33 beta (64-bit)" on both machines.

Here is my explanation (essentially confirming @DietrichEpp 's comment).

There are 3 attributes: 0:vNormal, 1:vTexCoord, 2:vPosition, and the main script makes hard-coded assumptions that the indices are precisely these (Note that it currently says "vColor" instead of "vTexCood", but I think that part is harmless.)

But when you add "v_Dot=1.", the optimizer (on the problem platform) notices vNormal is no longer used, so it removes it, and the attributes are now 0:vTexCoord, 1:vPosition, and so the main script's indexing becomes incorrect. Sort that out (i.e. remove all now-unused stuff and adjust the main script's indexing accordingly), and the program works again.

This is obviously really fragile, and I'm not familiar enough with webgl or opengl ES to say whether this shows a bug in the shader compiler/optimizer, or the main script, or the utility library, or some subset of the above, or something else.

I was just now doing a web search trying to figure out where to report this bug, and that's how I found your question.

0
votes

The dot product here represents the angle between the surface normal and the light. By forcing vDot to 1.0 everywhere, you're essentially asserting that 'there is no angle between the surface normal and the light'. So for every point on the surface, it acts like the light is directly above it and the surface is fully illuminated.