I’m confused why I have to use pre-multiplication to get correct lighting results when all samples seem to use post-multiplication without problems.
I created a simple example project, to isolate the issue. It contains a cube and a point light using basic Lambertian light calculation.
Standard post-multiplication results in incorrect lighting.
With pre-multiplication the lighting looks correct (identical to world space light calculation).
I haven’t tried your test app yet, but I should be able to explain a bit. Cinder uses the glm math library. It is designed to mimic OpenGL’s conventions. OpenGL uses row-major matrices. I always (still) have a problem remembering what row-major and column-major exactly mean, but I do know that row-major matrices need to be pre-multiplied to get proper results. Converting from object space to clip space, therefor, should be done like this:
This is because the w-coordinate is multiplied with the translation component of the matrix (the 4th row). Setting it to 0 disables the translation.
Note: when transforming directions or normals (which are basically also directions), you only want to apply the rotation component (and sometimes the scaling component as well), so in those cases you set the w-coordinate to 0:
Let me know if you still have trouble getting your calculations to behave. Make sure your C++ code also applies the correct multiplication order and you should be fine.