Search code examples
opengl-eslinear-algebranormals

Is this the work of messed up Normals or what could it be?


So I am taking a Graphics course and I am programming shaders. In the course we are given access to a service running webgl as well as a bunch of C++ code to compile to get an environment with a few models going. However, whether I compile this code on Windows or Linux does not matter, I don't get the result I am supposed to.

Sphere with a light orbiting it

So this is the result I get using the exact same glsl code as with this result:

WebGL version, slightly moved

I have not programmed C++ enough to debug the program yet but I suspect there is a bug in the program itself and not the shader, so I am wondering if anybody can, from experience, tell what kind of issue this is and then I will try to locate the code that would handle it.

My guess is that it has to do with the normals but I am not exactly sure as I just started with graphics and it was two years ago I did linear algebra properly. And as I don't know the C++ source (I'm analysing it right now so I can understand the flow) I don't know where to debug.

Vertex Shader:

....
attribute vec3 VertexPosition
attribute vec2 VertexST
attribute vec3 VertexNormal
....
void main(void) {
    Position = ProjectionMatrix * ViewMatrix * WorldMatrix * vec4  (VertexPosition, 1);
    Normal = normalize ((ViewMatrix * WorldMatrix * vec4 (VertexNormal, 0)).xyz);
    EyeSpaceLightPosition = ViewMatrix * LightPosition;
    EyeSpaceVertexPosition = ViewMatrix * WorldMatrix * vec4 (VertexPosition, 1);
    EyeSpaceObjectPosition = ViewMatrix * WorldMatrix * vec4 (0, 0, 0, 1);
    STCoords = VertexST;
    gl_Position = Position;

}

Pixel shader:

void main(void) {
    fragColor = vec4 (Normal, 1.0);  
    gl_FragColor = fragColor;
}

This code is what is actually running. There are declarations and stuff before, but yeah. There is more code in the actual files but they are commented so those lines don't run.


Solution

  • So the problem was solved and the reason was that in the vertex shader there are three declarations that tell the shader how in the array the information is ordered. It said:

    attribute vec3 VertexPosition;
    attribute vec2 VertexST;
    attribute vec3 VertexNormal;
    

    This is wrong, since the information that is given to the GPU from the CPU is actually ordered with Position, Normal, ST.

    That means they should switch and what happened was that the shader took the wrong piece of information and sent it onwards to the pixelshader that was the trying to do lighting without any normals (as I believe in this case we had no ST information, which I think is texture coordinates).

    This made the model not render properly as in the first picture in the question, but after switching these lines:

    attribute vec3 VertexPosition;
    attribute vec3 VertexNormal;  // Switched these two
    attribute vec2 VertexST;      // 
    

    Now the shader interprets the information given to it properly and the result is what is expected.

    EDIT: This is what was actually defined by the program and can be done in different ways. But in the case of the program I was given for my assignment, it was in this order. But as commenter said, it depends. But the problem was still that the order of declarations in the program differed from the order in the shader.