Strangely, it works correctly when I negate first, and then camera.tranform() it. I tested again using modelViewMatrix * originalLightPosition and it gives the same result. But it's different result when I camera.tranform() first, then negate it. What's going on there exactly? Wonder if I missed anything.