Search code examples
javascriptglslwebglwebgl2

Why is that the light is moving in this Webgl example


Here is an example of Goraud interpolation and a Lambertian reflection model from a textbook.

https://jsfiddle.net/zhenghaohe/r73knp0h/6/

However in the textbook there is a stupid error, in this book it says the code should contain this following line, when in fact it does not.

vec3 light = vec3(uModelViewMatrix * vec4(uLightDirection, 0.0));

The weird thing is the example still seems to work.

I am aware of that the sphere is rotating because

mat4.rotate(modelViewMatrix, modelViewMatrix, angle * Math.PI / 180, [0, 1, 0]); However it seems to me that the light is also moving with the sphere. But in the code I cannot find how the light is being moved around.

Can someone please point me to the code where we also rotate the light?


Solution

  • The light does not rotate, it is fixed in a static position and direction. The problem here is you do not seem to understand what a normal is and how it is used in computer graphics.

    A computer model is a series of "vertices" that connect to form "faces" (usually triangles). When "realistic" light is introduced into a scene an additional piece of information is necessary to determine how it should interact with each face of the model, this is called a "normal." A normal is a directional vector that generally forms a line perpendicular to a face, but it does not have to which will become important for your problem. This normal is used to compute how light interacts with that surface.

    So you have three sets of data: The vertices, the indicies (how the verticies come together to form faces), and the normals (computed automatically in your example). The problem arises when you begin to make transformations to the model (like rotation) but do not perform similar transformations to the normals that were computed before the transformation.

    Let's visualize this... say we have the following pyramid with one of it's normals drawn to illustrate the problem:

    Figure A

    Now when we start to rotate the pyramid, but we leave the normals directions unchanged we see that the angle between the normal and the face begins to change.

    Figure B

    Figure C

    For things to work as expected we need to also rotate the normals so that the angle relative to the face does not change.

    Figure D

    The angle of the light relative to the surface normal is what dictates how the surface is shaded by the light. When you're rotating the model the normals begin pointing in "random" directions, this messes with the light computation and it appears as if the light is rotating, but it is not.

    Obviously this is a very watered down explanation of what is happening, but it should give you a basic understanding of what a normal is and why you need to apply transformations to them as well.