Depth-writes for back-facing polygons only

Hi all,

I have a height field that’s drawing using a LOD algorithm so that it’s tricky to position other objects on top of it (because a given region might be drawn coarser than it actually is so that it pops into a building say that is supposed to sit on top of it).

I thought of a way to handle this which is this: since it can be assumed that there won’t ever be anything under the terrain I think I can safely omit writing depth values for front-facing polygons. All objects sitting on top of it will therefore pass the depth test and always cover the terrain. Back-facing polygons write to the depth buffer only so that the terrain still correctly occludes itself and any objects that are behind a hill say. I’m not entirely sure that this will always work (assuming again that there are no objects under the terrain for some reason) but a quick implementation seems to work.

The problem is that I can only think of two ways to do this. One is via a shader which won’t work on older hardware that don’t support shaders correctly, the other is via a multipass technique: draw back-facing polys with depth writes enabled and color writes disabled then front-facing polys with depth writes disabled and color writes enabled. This seems to work but drawing the whole terrain twice takes its toll.

Can any of you guys think of other tricks that would let me implement this behavior on older hardware? Comments on whether this makes sense at all for what I’m trying to do are also welcome.

Are you sure the coarse terrain will never be above an object on a backfacing face ? Because in this case it will show through and be very ugly.

About older hardware, I am pretty sure that there is no way to do this kind of trick on a single pass.

What about playing with glPolygonOffset instead ? Use different values for the terrain pass and the objects pass, so that object will be on top more often.

Are you sure the coarse terrain will never be above an object on a backfacing face ? Because in this case it will show through and be very ugly.

Unless my reasoning is off, if a back-facing terrain polygon is in front of an object that sits on top of the terrain then this means that said object is behind a hill or something and should be occluded. So back-facing faces write to the depth buffer and all other objects get tested against them. Which face will show through? Back-facing faces are never drawn in any case (to the color-buffer) so these can’t show through.

if a back-facing terrain polygon is in front of an object that sits on top of the terrain then this means that said object is behind a hill or something and should be occluded.

Indeed. But what if that object is even slightly below the terrain ? This is why I asked that question in my previous post.

Indeed. But what if that object is even slightly below the terrain ? This is why I asked that question in my previous post.

Well that’s the whole point. I haven’t been very clear probably. The problem is that I have the terrain and a road that’s supposed to be right on top of it. But as the road is polygonal and flat (following the slope of the terrain) and the terrain can get coarse further away from the camera it’s generally very tricky to keep it from poking out of the road here and there.

So what I wanted to achieve was to make sure that the road is always drawn over the terrain but still get properly occluded by it (for instance the parts that lie behind the hill you’re climbing right now).

If anyone’s got a better approach I’m all ears! I’ve tried with polygon offset but had no luck. The way I understand it it won’t work for offsets so big, being mainly designed for virtually coplanar polygons. Correct me if I’m wrong.

It is hard to communicate on a forum sometimes :slight_smile:

My point is that coarse terrain will sometimes be below and sometimes above objects (unless you have something that guarantee you will have only one of these cases, but it sounds unlikely).

Polygon offset with large values should be applicable to any situation. Be sure to try large values for both scale and factor parameters to push away the terrain depth :
http://www.opengl.org/sdk/docs/man/xhtml/glPolygonOffset.xml

EDIT: just found this which seems related to your problem :
http://www.mail-archive.com/osg-users@lists.openscenegraph.org/msg26186.html

Many thanks for the links! I gave polygon offset another shot and it does seem to work just fine. Trouble is I was more or less sure I tried this in the past without success (which is why I switched from LOD height fields to polygonal meshes for the terrain area around the track). I should perhaps further pursue this issue in a psychiatry forum. A title like “Brain getting overly creative without the use of medication” should do.

On a more graphics-related matter: the specification for polygon offset basically says that the quantities which get multiplied by the factors you specify in order to calculate the offset are implementation-dependent. Is it at all safe to assume that once suitable factors have been found on my machine, that they will work in other setups as well?

Is it at all safe to assume that once suitable factors have been found on my machine, that they will work in other setups as well?

Humm. No. Polygon offset is not gunaranteed to work exactly on another computer yet alone another platform. Each driver or implementation does something similar but slightly different. That’s the danger of polygon offset I’m afraid.

Hmmm, perhaps “something similar” is good enough. Given that the terrain mostly pokes out of the road less than say half a meter, overestimating and using polygon offset to push the terrain a couple of meters downwards (or rather depthwards) might do the trick. I guess experimenting is the only way to find out here.

EDIT:
More experimentation seems to indicate I was rash in saying that polygon offset works. No matter how I choose the units and factor the offset is usually too large at great distances from the camera and never big enough close by. To be more exact what happens is that when I get close to an area of the terrain the terrain suddenly pops out and I don’t think this is due to the LOD algorithm refining this area of the terrain because disabling lod updates doesn’t fix the problem. Does this happen because the offset is added after perspective division? If that is the case then there is no way to specify a uniform offset and this method won’t work.

Another possibility to consider is Lengyl’s projection offset trick (see this thread for code):