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, 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(
normalize(vTransformedNormal),
lightDirection));
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>
<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);
}
</script>
Thanks a lot, and let me know if there's anything else useful to add.
Dunno what the policy is around here for answering your own question, but in case someone stumbles upon this with the same problem:
I was transforming my light position by the model matrix. This doesn't make any sense, because the light position is already in world-coordinates, so there's no need to transform it at all.