Clip planes for large planet rendering

Started by
10 comments, last by _WeirdCat_ 4 years ago

Hi everyone,

I've got a question about how to set the clip planes for my camera when rendering real-scale planets. I think I've got most things figured out (render the scene with camera at the origin, store large positions as doubles then convert to float for rendering) but this is still confusing me.

Most people seem to say that you should set the far clip to a manageable value (e.g. 10,000) and then scale the planet down, but how does this work when I'm actually at the surface? If the camera's only 1m away, then scaling down the planet by, say, 1000x will make this equivalent to 1km. Then I'd have to move the near plane closer by a factor of 1000 to compensate for it, and the ratio between near and far makes the whole scaling thing pointless.

Any ideas of examples how I can render a planet while still being able to sit ~1m above the surface without clipping it out?

Thanks!

Advertisement

I am doing a similar thing (planet randerer), but i have paused that part of the project until graphics cards offer reasonable double performance because my lod algorithm does not have a mesh whose positions i could precalculate and pass over to the shader in a texture. I have to do the position calculations in the shader and that'll be too slow with 64 bit floats. But i see, the technology is coming to consumer grade cards as well (Radeon VII). Hopefully that trend holds.

To my limited knowledge, these are the options we have to control the depth range:

  • dynamically adjust near and far plane
  • make it linear instead of logarithmic
  • gracefully fade out the far reaches in the haze of an atmosphere. If there is an atmosphere :-)
  • Use a depth buffer with more than one frustums

For example, these links may give some more insight, i do not have more than the theory for now:

https://outerra.blogspot.com/2012/11/maximizing-depth-buffer-range-and.html

https://cesium.com/blog/2018/05/24/logarithmic-depth/

george7378 said:
does this work when I'm actually at the surface?

Well on the surface the view distance is pretty restrictive anyway so at some point you can render the local area as a regular terrain? Having a decent level of surface detail for the entire planet in one mesh is probably not practical anyway.

On Earth at sea level you can see about 4.7km, and you might have some “fog” to drastically cut that, or use physically smaller planets.

As altitude increases this does increase drastically, but being further away you need less detail, and none of it is really close so you can potentially also increase the near plane or scale the terrain itself.

Thanks for the replies - helpful stuff.

Adjusting the planes does make sense - I guess a clever combination of this with scaling could do it.

I think using atmosphere haze for games with flat worlds where the player is always close to the ground makes sense, but it doesn't really work when you're up in space and the atmosphere is a tiny blue line on the planet's limb (or, like you say, when there isn't one!)

Multiple frustums also makes sense - could probably get away with one from 1m-10km, and another from 10km to 100,000km. That would certainly be enough for my game world. Distant planets and moons would still have to be scaled so there'd have to be some algorithm to decide how to do that too. Also I guess you'd have to render everything twice if your planet is intersected by the boundary between the frustums?

Logarithmic depth buffer - this is very tempting. I haven't tried it yet just in case there's a more ‘accepted’ way to do it with the existing frustum limits, but it seems really easy to implement.

SyncViews said:

Well on the surface the view distance is pretty restrictive anyway so at some point you can render the local area as a regular terrain?

Good point - this could fit in with the ‘dynamically change the planes’ option to change the far plane to match the horizon distance. Ideally I'd find something that doesn't rely on the fact that the planet is spherical though - it would also be cool do draw something like a large ring-shaped space station where the user can sit 1m above the inside and look up at a arching huge structure 100km above them!

When up in space there is no need for precision at a distant planet. Even in low orbit 32 or even 24 bit of precision are enough, maybe even if one wants to display 3 storeys of clouds directly beneath and city lights at the horizon realistically from low orbit. Just push out the near plane as far as possible and drag in the far plane, which can be done every frame if quick changes happen, or limit the movement speed to one where the renderer can follow. Earth escape speed is pretty boring in real time :-)

One would probably have different scenes for orbital stuff views and ground stuff, but once we have double precision on the gpu even that is not necessary any more, a simple switch would tell the shader to render with double or single precision.

I once estimated the maximum to be possible with double precision (Sun in the center) to be in the range of Jupiter's orbit (or a ringworld, or a Dyson sphere/swarm).

I actually found an idea here which is interesting:

I exponentially scale down the distance so that everything past FCP/2 (out to infinity) is scaled down to fall between FCP/2 and FCP.

So setting far clip to 10,000 and scaling exponentially past 5000 might do it. I found an implementation with an example too - here, starting at line 82. This references a paper which I found in the internet archive here. The good stuff starts on page 23.

I guess the alternative is to use a logarithmic depth buffer which maybe achieves the same thing?

A third option might be to have two frustums - one from 1m to 10km and a second from 10km to 100,000km. Then a realistic sized planet could be done in two passes at full scale. Anything beyond 100,000km could be scaled and brought inwards in a third rendering pass.

george7378 said:
it would also be cool do draw something like a large ring-shaped space station where the user can sit 1m above the inside and look up at a arching huge structure 100km above them!

Well if you have the different levels of detail (since up-close you need a fair number of vertices to get many terrain features to look nice, you can't really render the entire planet/ring in that detail), then it seems the main issue there compared to a sphere is the “joins” as you go from very high detail to low detail sections would have to be visible, and you would need to line them up well enough.

I never did this on a scale that meant messing with the depth (just regular less vertices in the distance), but think should be able to get the maths to align.

Yep - I agree it would need LOD. I've got this going for planets, and I hate to think how I'd do it for an arbitrary real-scale space station mesh :S

Update for anyone interested - I tried out the exponential scaling method today, and have had success with it. One thing I did have to change though, was the far clip plane. When I left it at 10,000 to preserve the ratio with the near plane, there were lots of depth artifacts in the terrain when viewed close up. It looked as if the depth testing was almost non existent in some places. If I set the far plane to 10,000,000 though, these disappeared and it looks to render fine at all distances. Not sure why, but hey - it works.

Here's a simple moon-sized planet:

I am doing the same for my orbital flight simulator (large planet rendering). Only one problem is jittery when rendering life-size planet. I recommend a book called “3D Engine Design for Virtual Globes". It is available on Amazon and others.

This topic is closed to new replies.

Advertisement