Atmospheric Scattering - Reconstructing Positions from Depth Buffer

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

Recommended Posts

I've been working on an implementation of Eric Bruneton's atmospheric scattering effect for which the source code is provided here and I have run into a major problem with reconstructing 3d positions from a depth buffer which is needed for calculating the inscattered and reflected light. The problem is that my world and subsequent atmosphere is 6370 km in radius and the depth buffer I am using doesn't provide enough precision to reconstruct any useful positions (as all of it's values correspond to the far clipping plane [which is 100 million km out]). My response to this was to use a logarithmic depth buffer which provides far better precision for these type of large scenes and apparently it works until I attempt to reconstruct positions from it - then it seems to fall apart for some reason and produce almost the same results as the standard depth buffer. There are some screenshot below demonstrating this - the left half of each image shows the normal depth buffer and its results and the right shows the log depth buffer and its results, the top half shows the atmospheric effects rendered and the bottom half shows the depth buffers themselves.

This image shows how the log depth buffer appears to work yet has the same results.

This image highlights the overall problem of the positions not being reconstructed properly, thus all of the terrain is considered to be the same distance as the sky is from the camera while it may or may not be much, much closer, therefore the terrain appears transparent.

The same image is as the previous one but without any atmospheric effects or gbuffers, showing some pure white, "snowy" terrain.

I've checked and rechecked pretty much all of the code that produces the atmospheric effects multiple times, the only problem appears to be the bit already explained above. My only guess is that for some reason the log depth buffer isn't being linearized. Here's the vertex shader code that produces the log depth buffer (GLSL).

void main ()
{
vec4 pos;
pos = (gl_ModelViewProjectionMatrix * gl_Vertex);
pos.z = ((log2(max (1e-06, (1.0 + pos.w))) * (2.0 / log2((_Farplane + 1.0)))) - 1.0);
pos.z *= pos.w;
gl_Position = pos;
}
//_Farplane is the camera farplane which is 1e+11

And this is how the positions are later on reconstructed in the atmosphere fragment shader.

float depth = tex2D(_DepthBuffer, input.uv);
vec3 worldPos = g_cameraPos + input.cameraToNear + depth * input.nearToFar;
//input.nearToFar is a vec4 that = farFrustrum - nearFrustrum
//input.cameraToNear is a vec4 that = nearFrustrum - g_cameraPos

To my knowledge this should work and I can't figure out why it doesn't. If anyone else has accomplished what I'm trying to do can they explain how their setup worked? Otherwise, does anyone see what's not being accounted for in my code?

Edited by SkavenPlanet

Share on other sites
Your custom depth is logarithmic, but your reconstruction looks ... quite linear. There should be a pow or exp at least. Here's a similar discussion with a solution (DX though).

You could use Wolfram Alpha to get the inverse function

Share on other sites

Unless you are expecting to view the entire planet at once, there is no need to use the entire planet radius as your far clip plane, visually its impossible to see that far anyways. The math involve using that radius to calculate inscattering and outscattering, but your world doesn't have to have the same scale. Are you rendering a skydome that large ? or do you required that large of a view distance ?

Share on other sites

Unless you are expecting to view the entire planet at once, there is no need to use the entire planet radius as your far clip plane, visually its impossible to see that far anyways. The math involve using that radius to calculate inscattering and outscattering, but your world doesn't have to have the same scale. Are you rendering a skydome that large ? or do you required that large of a view distance ?

The game's world isn't a flat terrain but consists of multiple planets on a realistic scale. If you look in the first image the camera is viewing the entire planet at once, the far clipping plane is way further out than the planet radius is, and for my game's purposes players are supposed to be able to see a jupiter-sized world from millions of kilometers away hence the 1e+11 far clipping plane - this works for the planetary terrain renderer w/out the scattering effect, just not yet for the scattering effect. Just to clarify the "skydome" would be the actual atmosphere of the planet so yes, it does, more or less have the same radius as the planet.

Edited by SkavenPlanet

Share on other sites

Nevermind... think I got it figured out.

Edited by SkavenPlanet

1. 1
2. 2
3. 3
Rutin
16
4. 4
5. 5

• 14
• 9
• 9
• 9
• 10
• Forum Statistics

• Total Topics
632915
• Total Posts
3009197
• Who's Online (See full list)

There are no registered users currently online

×