Bug in Bump Mapping?

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 {
                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"? ;)

I don't use dot3 bumpmapping myself.  But if there's a problem with it you feel you have solved, go ahead and submit a test case and/or patch. :slight_smile:

You should probably try a different (simpeler) texture first, to see if the problem is not because of the texture.

Like renanse said, an issue and/or a patch would be the way to go forward

@renanse: Just mailed you the patch for the problem with directional lighting.

As for the other lighting problem, I already did some debugging. The transformation of the light vector to model space, the computation of the TBN matrices and the transformation of the light vector from model space to tangent space are all done properly. I'd expected the reason for the problem there, but it seems I was wrong. I'll have to do some more testing before I definitely consider this a bug and submit an issue to the tracker (and maybe even find a solution). I'd really appreciate if someone else could test it and tell me if he/she sees the same buggy results :wink:

@llama: Using a simpler bump map texture is a good idea, I'll try that out… Do you have some (links to) textures I could use for this?

No idea, but a few google queries give me this for instance:

Simple OpenGL Bump Mapping Tutorial - Paul's Projects

(most other tutorials seem to use the same texture as us!)

I think there’s a pretty good texture for debugging in there. wrong link, see below

Tried some textures from the web… For most of them (including the one from Paul's Projects) the problem was less noticeable, as they were less symmetric as the one I used in my first test, but it was still present. What I could really use would be the normal map of a hemisphere as a normal map texture. I tried creating one myself with 3DS max, but that didn't work at all (maybe I'm too stupid for this ^^)…

By the way, I noticed that for some of the normal map textures, the Y coord of the normals in the map (that is, the green channel) was inverted, whereas for other textures, it was not. Therefore I added a switch to the BumpMapColorController which defines whether the Y axis of the TBN matrix should be inverted or not, in order to compensate the flipped/not flipped Y coords. This at least fixed the problem with the flipped Y axis in jME's bump mapping test I mentioned in the first post, when I deactivated Y axis flipping in the test (default is "active"), so I'll post this as a patch again.

However, the "precision" problem in my own little test scenario remains the same. I'll keep looking further into this…

uh, sorry… try this one:

http://www.codesampler.com/source/ogl_dot3_bump_mapping.zip (test_normal_map.bmp)

Ah, perfect, that texture is just what I was looking for! Thanks!

Here are the results with this new texture, the scene setup is the same as before:

You can see clearly from the images that there’s something wrong with the lighting. It seems like the light is not rotating around the Y axis of the cube, but rather around some diagonal axis - in the third screenshot the light appears to coming from almost directly above the cube. This can not be a problem on the side of the scene setup because, as I mentioned before, the results are the same if I rotate the cube instead of the light (and you can also tell from the shadow cast by the cube that the light is not directly above it :wink: ).

I really wonder what’s going wrong here… The light vector, local light vector, TBN matrix, tangent space light vector and working color are all okay, yet the lighting is wrong. Could this possibly be a problem of the underlying graphics library?

I'm not sure what the issue is, but I see it too.  To me it looks like a math issue.  If you throw a sphere at the inverted light direction (scale the negated direction to fit your scene) you can see that the light direction rotated around the Z axis nicely.  You can also see that the sphere is properly lit as you would expect.  So that just leaves a math issue of some sort.

since this is about bump mapping - in my dungeon, i'm using the dot3 bumpmapping from testbumpmap using the player as a lightsource, but the shadows don't change when the player/lightsource moves. does it only work with directional light?

Actually, a PointLight should work too - at least it does in my test app :wink:

Did you add a BumpMapColorController to each bumpmapped object and set the bumpmapped object as a target for the controller?

i didn't know there is such a controller. didn't see one in testbumpmap.

HamsterofDeath said:

i didn't know there is such a controller. didn't see one in testbumpmap.

its under the jme.util package called BumpMapColorController

how did you change my local source to contain a bumpmapcolorcontroller? i almost certain there wasn't one the last few times i looked at the code :expressionless:

HamsterofDeath said:

how did you change my local source to contain a bumpmapcolorcontroller? i almost certain there wasn't one the last few times i looked at the code :|

coz i can hack into ur computer  }:-@