I'm working on a simple phong shader in webgl, and I think I'm getting close but something is still wrong. Dead give away: if I have a billboard and have it roll (so it spins like a wheel), the part of the billboard that is lit up spins with it :(. This confuses me, because it seems like a problem with the model matrix, but the transform makes all the positions & rotations correct, and lighting math is done entirely in world-coordinates , just the lighting wrong. Ditto with the view matrix, I can move around and look freely and everything is located in its proper place, just lit wrong.

Here are my shaders (minus the definitions for space, and with the lighting in the model matrix moved into GPU for clarity) {if you prefer reading in github: https://github.com/nickgeorge/quantum/blob/master/index.html#L41}

<script id="fragment-shader" type="x-shader/x-fragment">
  void main(void) {
    vec3 lightWeighting;
    if (!uUseLighting) {
      lightWeighting = vec3(1.0, 1.0, 1.0);
    } else {
      vec3 lightDirection = normalize(vLightPosition.xyz - vPosition.xyz);

      float directionalLightWeighting = max(0.0, dot(
      lightWeighting = uAmbientColor + uPointLightingColor * directionalLightWeighting;

    vec4 fragmentColor;
    if (uUseTexture) {
      fragmentColor = texture2D(uSampler, 
          vec2(vTextureCoord.s, vTextureCoord.t));
    } else {
      fragmentColor = uColor;
    gl_FragColor = vec4(fragmentColor.rgb * lightWeighting, fragmentColor.a);

<script id="vertex-shader" type="x-shader/x-vertex">
  void main(void) {
    vPosition = uModelMatrix * vec4(aVertexPosition, 1.0);

    // TODO: Move back to CPU 
    vLightPosition = uModelMatrix * vec4(uPointLightingLocation, 1.0);

    gl_Position = uPerspectiveMatrix * uViewMatrix * vPosition;
    vTextureCoord = aTextureCoord;
    vTransformedNormal = normalize(uNormalMatrix * aVertexNormal);

Thanks a lot, and let me know if there's anything else useful to add.

  • \$\begingroup\$ I wanted to try your project but it is incomplete on github. population/hero.js and gl/webgl-utils.js are missing. \$\endgroup\$ – rioki Apr 21 '14 at 18:34
  • \$\begingroup\$ oops, fixed. Press G to enable mouse look, light is in the upper-left corner (blue cube), and the wall is rotating to show the problem \$\endgroup\$ – Nick Apr 22 '14 at 0:40

The problem with the code is that you are transforming the light with the model matrix, that is the position and orientation of the object you are rendering.

| improve this answer | |
  • \$\begingroup\$ hmm, I don't follow- The math gets done entirely in world-coordinates. It doesn't care where the camera is. How does it make sense to do math with an object in world-coordinates and lights in camera-coordinates? \$\endgroup\$ – Nick Apr 22 '14 at 0:39
  • \$\begingroup\$ Oh Oh Oh!! I get it. It doesn't make sense to multiply by the view matrix (b/c the math gets done in world-coordinates) but it also doesn't make sense to multiply the light position, because it's already in world coordinates! Thanks a lot. Can you please take out the bit about the view matrix in your answer, just so as to not confuse other visitors? \$\endgroup\$ – Nick Apr 22 '14 at 0:52
  • \$\begingroup\$ Well it depends, you may make the lighting computations in view space and thus would need to transform it by the view matrix. But that is not the common case, thus I took it out. \$\endgroup\$ – rioki Apr 22 '14 at 12:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.