Hi everyone!
I recently tested bump mapping again, but although it worked when I tested it the last time, it showed very strange results this time. I can’t really tell what’s going wrong… When I tried using the bump map from here on a regular cube, I got totally strange results. Here are four screenshots of a scene with a bump mapped cube viewed from above, with a rotating light source. The cube’s edge length is 10, the light source is (33, 90, 33) above it, rotating around the Y axis of the cube. The shadow behind the cube shows the position of the light in each screenshot.
The first image appears correct. In the second image, the right edges of the “flagstones” are a bit too bright. The lighting in the third image appears as if the light was way above the cube, and the last one is almost correct again, though the top edges are a little too bright. The results are the same if I rotate the cube instead of the light source.
The results in the bump mapping test (jmetest.effects.TestBumpMapping) were wrong too - the lighting was always inverted on the Y axis of the bump map texture.
The bump maps behaved even more strangely when using them on transformed objects together with a directional light. I already mentioned that issue a while ago, here (You can try it out yourself by rotating the torus in TestBumpMapping). When I first discovered the problem, I already suspected that lines 194 to 196 might be the reason:
if (l.getType() != Light.LT_DIRECTIONAL) {
batch.getParentGeom().worldToLocal(lVect, lVect);
}
The direction of the light is not converted to the local coordinate system of the bump mapped object, thus the error. Back then, I thought removing the if statement might fix it, but I found out that the method worldToLocal(...) of Spatial actually transforms points in space, not directions. Therefore I added an else statement for directional lights:
if (l.getType() != Light.LT_DIRECTIONAL) {
batch.getParentGeom().worldToLocal(lVect, lVect);
} else {
lVect.divideLocal(batch.getParentGeom().getWorldScale());
batch.getParentGeom().getWorldRotation().inverse().mult(lVect, lVect);
}
This properly transforms the (inverted) direction of the light into the local coordinate system. With this change, the bump mapping with directional light behaved exactly the same way as with point light.
However, the overall problem remains: Why do the bump maps act so strangely lately? And btw, did anyone else ever notice that problem, or is it "just me again"? ;)