How to deal with large depth buffer values due to extreme distances

Alright, this is semi-related to my last question here

So I've got an really big coordinate system and need to handle rendering large astral bodies from extreme distances. My current approach involves different rendering passes based on the distance of the object. The extremely far objects are simply rendered first without writing to the depth buffer using a painters algorithm, while the closer objects are ran through my standard pipeline.

This works however, it isn't ideal for me. The problem isn't when the planet is far enough to fit on the screen. The billboard technique Nicol mentioned below works fine in this case. However, it's when the player is in a fairly low orbit from the surface. I can't use a billboard and would like the terrain to be able to run through my standard pipeline to make it nice and properly lit. With my limited depth buffer though, this isn't possible without z-fighting or letting it clip past the far plane.

My question is are there any other approaches I can take? I'm looking into using a linear depth buffer but this doesn't sound too easy since DX11 only supports a floating point depth buffer and I would have to implement all the z culling functionality and what not myself with a standard render target.

2 Answers

need to handle rendering large astral bodies from extreme distances

Consider the scale of the Solar System. 8 planets, and we're currently on one. Our closest neighboring planet, Venus, is almost the same size as Earth. Yet, it is so far away from the Earth that it appears as nothing more than just another star in the sky. Jupiter is the largest planet in the Solar System; its radius is approximately 11 times the radius of Earth. Yet again, it is so far away that it appears as nothing more than a point of light with the unaided eye.

The Sun itself has 100x+ the radius of the Earth. It is absolutely immense. How big is it from the Earth? Not very; it appears as a small disk in the sky.

The Solar System is gargantuan! If you're close enough to a planet to be able to see that it isn't just a faint star, odds are good that there will be no other planets nearby enough to be able to see as anything more than a star in the sky. Moons of that planet may have visible details, but that's about it.

"Large astral bodies from extreme distances" are points of lights. They don't need to be anything more than that.

If you're making a space game, you can represent a planet as simply a textured sphere. There shouldn't be any z-fighting, because it's just a sphere; it can't z-fight with itself. Indeed, you can probably represent the planet most of the time as a simple flatcard impostor that grows and shrinks as you approach it. You'd use some shader logic to orient a cube map or two onto it of course.

If the planet is close enough for parallax to matter, then you could either use a ray-traced impostor or just render a sphere of the appropriate size. Either way, you use a projection at infinity to make it work, so that it doesn't overlap with the depth buffer.

Now, you may ask what happens if something moves behind the planet? Well, that something would have to be another celestial body for you to notice. Remember: space is big. No, bigger than that. If a ship is far enough away to duck behind a planet, then it was almost certainly far enough away that you can't see it anymore. So you need not worry about it.

Any celestial bodies large enough to overlap with the nearby planet can be handled very easily. They're spheres/impostors/etc: render them farthest to nearest. No need for depth buffering of any kind.

I can't use a billboard and would like the terrain to be able to run through my standard pipeline to make it nice and properly lit.

Terrain doesn't have very many details that you could pick out from low-orbit. All you need is a reasonably-sized bump map on your billboard.

Take a look at the Planet Earth documentary, which has some shots of Earth from relatively low-orbit. Bump mapping should really be all you need.

I think you're trying too hard to make everything "realistic" when you should be focused on making your game. Just get something that looks reasonably good; don't try to do everything exactly how it works in reality.

• I agree with everything here, but I'd still like to see some "real" answers to handling large coordinate systems. – notlesh Jan 28 '12 at 23:08
• Edited the question to try and clarify my issue better. It's the the low orbit I'm mainly having issues with. – KlashnikovKid Jan 28 '12 at 23:31
• You're right. I am over thinking this a bit. I'll take your advice into consideration and play around with an impostor for the low orbit. Thanks for the help! Going to leave the answer open for a day or two just in case there are other clever alternatives. :P – KlashnikovKid Jan 29 '12 at 0:15
• @stephelton there is no "real", it's a simulation, its all fake at the end. If it wasn't, then you were creating a universe, that however would give you much more headache, than just z-fighting :p long story short, say goodbye to "real", just make it look and feel good - +1'ed btw – Maik Semder Jan 29 '12 at 15:32
• @MaikSemder, notice I put "real" in quotations :) – notlesh Jan 29 '12 at 15:54

Alright, figured I'd also post my technique that I ended up using.

As mentioned before, I wanted to render the planets through my deferred pipeline. (rendering to one of my buffers alone with a single pass first would cause side-effects due to ambient light during compositing of all the render targets)

I realized that I could easily do this by using two depth buffer and projection matrices. First I render the distant low resolution bodies and other significant sized objects (Dreadnought ships in my case) with a far set of clip planes and their own depth buffer, and then the closer objects and terrain (if I'm close enough to the surface) with another projection matrix and depth buffer. If you adjust your clip planes you can easily render near and far without any z-fighting.