better bump mapping

Has anyone ever tried this? It’s probably already been invented, but I’ve never seen it before so I thought I’d program it. It’s a little better than plain bump mapping, but not as accurate as displacement mapping.

It only works well with low-frequency bumps. Sharp angles cause some annoying artifacts.

Linux demo (requires GLUT, ARB_vertex_program, and ARB_fragment_program.)

[This message has been edited by mogumbo (edited 01-12-2004).]

[This message has been edited by mogumbo (edited 01-12-2004).]

The shot looks very nice, perhaps you could do something about those silhouettes to get them right too?

So how do you do it?


Really nice !

Does it works only with cylinders or such simple geometry ?


Could you tell us, how you did that?
And could you post a screenshot of the not-bumpmapped image? I´d like to see the real difference.


The source seems to be included, why not check it yourself.


Looks nice and (I didn’t look at the source) reminds me of this:

Check out the 2003 SIGGRAPH proceedings for a correct silhuette: “View-Dependent Displacement Mapping” from Lifeng Wang.
Found a link on

That view-dependent displacement mapping is really cool, and way more complicated than what I’m doing. Maybe I’ll tackle that later on.

I guess I could have been more descriptive when I posted this. Just figured demo said more than I could. The meat of it is in these three lines of the fragment program:

TEX height, fragment.texcoord[0], texture[2], 2D;
MAD height, height, 0.04, -0.02; # scale and bias
MAD newtexcoord, height, eyevects, fragment.texcoord[0];

All I do is get the height of the surface from a 1-channel texture. Then I scale it down. Then I multiply it by a tangent space vector pointing to the eyepoint and add that to the main texture coordinate. The new texture coordinate is used to index the regular color texture and the normal map for bump mapping.

It should work on any geometry. In the demo I applied it to a flat surface and a curved surface just to see how it looks.

I have to agree it looks very cool, and also sounds quite simple to implement, and fast.

What kind of artifacts do you get with sharp angles ? Can you post a screenshot ?

No Linux machine with ARB_fragment_program at my disposal right now, i might try to port it to Win32 if i have time tonight.

Does it look correct when the camera is moving too ?


The sharp angle artifacts look like this . As you can see in the lower-left corner of this image, though, low frequency bumps look pretty good still. You need something like VDM to do this accurately. This is more like poor-man’s diplacement mapping

It works alright at any camera angle because it is computed with a vector pointing to the eye. I should have mentioned in my previous post that the tangent space eye vector is calculated in a vertex program, similarly to the way you compute a tangent space light vectors for bump mapping.

I compiled it for windows, let me know if you want it removed from my webspace.

It looks sweet!

Wow, just wow. Indeed i can’t find any good reason to not use this technique at a bigger scale (understand: for all the materials of a game, for example).

It makes a world of difference when zooming close to the surface. Ex.: (normal bump mapping) (offset bump mapping)

The sharp artifacts aren’t too bad comparatively to the small price you pay for the increase of quality…


I don’t know. Those sharp angle artifacts still bug me, but it works well for certain types of textures. Organic things with lots of curves seem to look fine with this technique. Now I want to try to implement the VDM method that Relic posted, but that will take some time and be way more computationally expensive.

Thanks for the Windows version, ml.

I do not have a complete understanding of the tangent space, so I might be talking complete crap, but I assume that we can compute the tangent space vertex value.(vertex coordinate in tangent space).

If you interpolate that for the fragment program, then you could add the height and calculate the tangent space eye vector from the tip of the bump instead of the polygon surface and maybe that would help with the artifacts.

That’s of course assuming it’s possible to to get a vertex position in tangent space.

I believe, by the definition of tangent space, the z value of any vertex in tangent space is zero. However, it might be possible to modify the eye vector in the fragment program before computing the texture offset. I think you would have to pass information to fragment program to tell it the scale of the texture or something like that. Rrrg. That makes my brain hurt :stuck_out_tongue:

Is the parallax effect correct in the sense that if you mix your bumps with real geometry, will it look funny?


It’s not perfect, but you could adjust the scale and bias to make it look right for different surfaces. After all, computer graphics is just a bunch of approximations.

mogumbo :
very nice effect, and so easy to implement. Indeed a very clever idea to express the eye vector in tangent space.

Could you explain how you got those 0.04 and -0.02 for scale / bias ?

Maybe it could be possible to deduce them mathematically for each pixel, and would reduce the artifact you get on the too vertical displacements ?

I’m going to add this to my island scene to see if it gets better look. If it does, I’ll post screen shots.


It’s really nice looking. I just had to get the correct glut32.dll first.

I think this is about a perfect algo for 2d games in a 3d world. I’m thinking of Duke Nukem - Manhattan Project style games. It would add a lot of depth, i guess.

The scale and bias are just estimates, and if you used this fragment program for a wide variety of textures you would probably want to pass the scale and bias as a local parameter.

The correct value for the scale would be the texture’s physical height divided by width. For example, a texture of sand on a beach might cover 5x5 meters while the dips and ridges in the sand rise .2 meters. The correct scale would be .2 / 5 = .04.

Setting the bias to ‘scale’ * -0.5 puts the reference plane right at the median height of the texture.

Real nice effect, I notice in the fragment program you do

remove scale and bias from the normal map

SUB normal, normal, 0.5;
MUL normal, normal, 2.0;

Any reason you cannot do?
MAD normal, normal, 2.0, -1.0;