I need to manipulate the depth buffer. Are stencil buffers the way to go?

Started by
6 comments, last by CGameProgrammer 17 years, 1 month ago
(BACKGROUND) I'm modifying the Dapple code, which is a modification of NASA's WorldWind project, and terrain is rendered quite sloppily. You can have multiple layers of terrain active, meaning the earth might be rendered using a very low-resolution texture, and then the ground near you may be rendered on top of that with high-detail images. The actual polygons are completely different; it's not drawing the same triangles with different textures. Because of this, you get something like z-fighting except that the polygons aren't actually coplanar; it's more like cross-stitching of polygons. The original solution was to clear the z-buffer before each patch of ground is drawn, but that defeated the whole purpose of using the z-buffer as it caused z-buffer errors. I hacked a solution where it clears the z-buffer only when a new layer is about to be drawn, which makes the terrain render correctly. However, it's impossible to draw objects on the terrain as they'll either always be hidden or always be shown, since the z-buffer is being cleared. (PROBLEM) Basically, there are a few ways to fix it: * Render the terrain as above, then do a second render-pass but only to the z-buffer. Or: * When drawing a terrain layer, overwrite the previous z-buffer values unless they were created by that same layer. The first solution seems the simplest but I'm not sure how. The extra time spent rendering will not be significant. I also don't know how to do the second solution. Stencil buffers? I've never messed around with those. EDIT: After further thought, the best solution is to render each layer to a separate surface, then render one surface on top of the other, with depth-testing disabled but depth-writing enabled. That way each layer will still do depth-testing with itself, but not with the layer underneath, and the finished scene will have intact z-data for everything so objects can be drawn on top. Well I guess this post doesn't have much purpose unless I can't figure out how to do the above. [Edited by - CGameProgrammer on March 2, 2007 7:56:30 PM]
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
Advertisement
If you have two intersecting triangles, will the line at which they intersect look jagged due to depth fighting? If this is the case, try using a higher resolution depth buffer (D24S8 instead of D16whatever). If that doesn't work you can try reducting your far plane:near plane ratio, and you'll get a better distribution of depth values.
No, that's not the issue. The issue is that some polygons that are behind others still need to be drawn over them.
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
If you have polys that don't match up, you're going to have rendering artifacts - that's pretty much unavoidable. You need to decide which set of artifacts are acceptable to you.

What I'd probably do is render the base geometry with z reads and writes, then render any subsequent "detail" terrain geometry with z reads on, but z writes disabled. Then render the objects, characters, and buildings or whatever with z reads and writes on. With this, you'll lose any of the "detail" terrain geometry that conflicts with the base geometry or subsequent stuff, but, well, if that's the data you've got...
I can't do that because the detail layers won't do z-buffering with themselves, and I need them to. I think the solution I suggested is the one I need, but I don't know how to render a quad that already has its own z-buffer.
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
Try using the depth bias, you can find stuff about it in DX Reference at Advanced Topics/Pixel Pipeline. Or simply try to draw the upper poligons a bit higher.

You should put a picture here, it would be more clear.
My solution was to render each layer, with z-buffering enabled, to separate surfaces, then paste one layer on top of another without z-buffering, with undrawn pixels being transparent. How do I go about doing that?

To illustrate the problem, here is the bottom layer:


Here is the smaller detailed layer:


Here they are, drawn together:


That is not z-fighting; the polygons are totally different. Some of the detailed layer's polygons are lower than the other layer's, and some are higher. Vertices are totally different, not just height values, but X and Z as well.

If the z-buffer is cleared before each new layer is drawn, you get this:


...which is correct. However, because the z-buffer for each previous layer is thrown out, it is no longer possible to draw objects on the ground correctly. For example, this following screenshot:


The jagged red line on the bottom is drawn at ground level but you can see it through the mountains because z-buffer information for that layer was discarded.

Actually, what I could do is render the detail layer(s) with z-reading disabled, then render them again with it enabled. That should fix everything, albeit at the cost of speed. I'll try that.

[Edited by - CGameProgrammer on March 5, 2007 12:08:57 PM]
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
I got it working! Whew. I render the detail layer twice, first with z-reading disabled to wipe out the previous z-buffer only where the detail is drawn, then I render the layer again with z-reading enabled. It has to be rendered again to make sure it does z-buffering with itself.
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.

This topic is closed to new replies.

Advertisement