Jump to content
  • Advertisement
Sign in to follow this  
CGameProgrammer

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

This topic is 4152 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

(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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Guest
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!