new Relief Mapping shader (better Parallax Mapping?!?)

Hi… I just finished a new Relief Mapping shader that looks excellent!

It is similar to Parallax Mapping but uses a binary search to generate accurate per-fragment offsets also including self shadows and correct Z depth values.

Only a single quad is drawn in a single pass. It only uses a color texture (RGB) and relief texture (RGBA, normal map + depth map in alpha channel).

The shader is big (around 200 assembler instructions) but runs fast on new video cards such as the GeForce6 (over 100 fps at full screen).

Check out the demo at:

Also the updated documentation including details on the new corrected Z option at:

Now I’d like to support curved surfaces but my first thoughts on the subject could not find a simple implementation to it.

The demo uses CG and OpenGL and needs latest NVidia drivers 61.77. It will not run ATI cards as fragment shader is too long.

I also would like to try a comparison of this technique with original Parallax Mapping using same texture maps. Does anyone here have a Parallax Mapping implementation to compare it to?

Thanks for any feedback on the new shader…

Doesn’t work here, I have GF 5200 and 61.77 drivers. All I see is black background and white wireframe square, which moves as i drag mouse. Strangely, Wireframe option is enabled by default, but changing it doesn’t help. Tried to experiment with settings, then load relief and color maps manually - still got no change. (BTW it is annoying when the open dialog starts at file system root rather than the dir where the app started). CPU seems not busy much.

Very cool, it works very well on a 6800 for me, I remember there was some discussion about iterating the depth offset in the original parallax mapping thread.

FWIW I’d rather you stuck with a similar name like iterative parallax mapping or refined parallax mapping or some other appropriate variation. It seems like there’s enough in common with the original algorithm to stick with a similar name.

In addition the displacement in parallax mapping along the view vector in tangent space is not entirely arbitrary, it should be stated that it is scaled by tan of the angle of incidence in your paper (first sentence in section “2. How it works”). There is an arbitrary factor in there but IMHO this is a height scale factor. Obviously you know this but I think it is worth clarifying when you’re publishing it like this.

I’m left wondering how well it will work on curved surfaces, I don’t think you should restrict yourself to planar solutions, rather you should treat pixels on curved tangent space (i.e. interpolated vectors from different per vertex coordinate frames) with the planar intersection solution at each pixel and see what is produced. It will be an approximation but probably a better one than parallax mapping. Have you tried this? How well did it work?

I’m not sure that the term “mapping” should even apply to this technique. Not that the technique isn’t good (though quite expensive), but it’s just that it isn’t really texturing (though textures are being accessed). Instead, it’s, effectively, raytracing a heightmap. It doesn’t really seem very similar to the parallax technique, if it is doing what I think it is doing.

Parallax mapping samples height and fetches an offset rgb. This samples height and uses the result to sample height again etc until it uses the final result to fetch rgb. It’s kind of an iterative parallax indirect fetch. The actual function name “ray_intersect” is infact an iterative search through multiple offset offset fetches (yes offset offset is not a typo).

I still think there’s nothing stopping this working well in curved tangent space although silhouettes are still the Achilles’ heel.

but runs fast on new video cards such as the GeForce6 (over 100 fps at full screen).

What resolution and quality settings? On my 6800 GT I’m getting 60fps fullscreen. My settings are: 1024x768, AA at 2xQ, anisotropic at 8x, Images settings at Quality, vsync off and so on.

I really like this technique though.


In windowed mode it runs about 106 fps for me
Full screen it’s 145 (dunno what res it doesn’t ask me anything but it looks like 640*480)
(On a geforce6800 GT that is)

It is difficult to name it as it is somehow like Parallax Mapping but also different and similar to ray-tracing the depth map or Relief Texture Mapping.

Anyway, looks nice on some objects if feature details are not too small (smaller than liner step size). I think it would look nice on walls and panels like the ones made for Doom3 (or like my tile1 sample).

And I also have a GeForece6800 GT. The fullscreen mode I talked about was 640x480 (use Alt+Enter in my demo and not maximize for game like full screen mode).

I looked at the ini file and the default is 640x480. So when I run in that res instead of 1024 I get the same peformance as Pentagram.


Great so… have you checked the other maps included like the relief.rm?

I want to make a nice room now with all geometry using it to see if several relief maps together still runs fast. Turning mip-mapping on makes it faster when using larger tile sets (use +,- keys to select the tiling mode).

The F4 keys will switch to observer mode where you can fly anywhere in scene with arrows and S/X keys.

I have a ATI9800 but it will not run this shader (too long too many texture reads).
Anyone knows if new ATI X800 videocard can do larger programs or more texture reads? Or is it just a faster ATI9800 but same shader compexity support?

Originally posted by fpo:
Anyone knows if new ATI X800 videocard can do larger programs or more texture reads? Or is it just a faster ATI9800 but same shader compexity support?[/QB]
Yes it can do 512 instructions of any type (texture or ALU) but the limitation of only 4 level of texture indirections remains.

Ok, I posted a new version now that can switch between ARBFP1 and NVFP30 profiles. I think someone with a ATI X800 card mmight be able to run it with the ARBFP1 option now.

Please, if someone here can run this on a new X800 ATI card please posts results here.

doesn’t work on my FireGL X2.
probably too many texture indirections.

fpo, you still haven’t said why you limit yourself to planar faces, I think you’re selling your technique short. Sending the interpolated tengent space vectors to the fragment program should just work after some (optional?) normalization.

hi dorbie… the problem with tangent space is that on a curved surface, the ray used to ray-intersect the depth map should be curved in order to get the correct outlines at silluete.

only using tangent space (and no surface curvature information), when rendering a fragment we would be considering the surface flat at that fragment.

and in my shader I use the uv mapping information to project any point in the object space into the texture map… but I think this could be solved with some aproximation of the mapping function.

I will try it over the weekend to see if I can get somewhere with it. I have another displace map demo that uses tangent space and maybe I can use the same approach there with this new shader.

I understand this, but I don’t think it is a problem. Having a true curved ray treatment would cause more problems than it solves when you consider that the curvature would change across facets and a fragment cannot track this, it would therefore lead to discontinuities between facets. The straight ray approximation after surface contact is still a better solution than previous approaches and may even be a necessary approximation on a surface of varying curvature.

You still have silhouette issues (offset clamping has been proposed in the past), but other solutions have these issues.

thanks, I will try that so… it would be excelent to see those relief maps applied to any geometry.

We had a long holiday (monday and tuesday) here in Brazil and I have accumulated some work I need to finish for tomorow. I will try to implement the tangent space version as soon as possible (maybe over the weekend). If need any help I will post something here…

Thanks for the support dorbie… see you are from san diego… was in LA a few weeks ago… nice time there.

Wow wow wow. I’ve seen it all now. One quad. Stunning.

Playing around with this demo a bit more I found some spots where some artifacts pop up. Here is a screenshot:

Also I noticed that this technique from a distance looks quite good, but once you get close to the surface things start to look really bad. Not only are you getting those black spots as shown above, but also the lighting looks streaky, jaggy black areas, pixelation, specular highlight is warping all around, etc. I’m sure this can all be resolved but currently it has many problems at close up.

EDIT: BTW, for that link to work you have to copy it and paste into the address bar.


Yes… there are some artifacts if you move too close and with angle almost parallel to polygon. But if you compare that close view to the normal map version it will still look better.

Also, there is a double precision option in the demo that will make things look much better from close ups (Ctrl+P I think) but double the texture reads.

It is not a perfect solution but im many cases look better than same thing with only normal mapping even with the artifacts. If you make panels with a reduced depth range things will look even better (too deep objects are a problem).

You can also make higher resolution maps (included samples are only 512x512).