Irbis
Irbis

Reputation: 13369

atmospheric scattering and sky geometry

I'm trying to implement an atmospheric scattering in my graphics (game) engine based on the gpu gems article: link. An example implementation from that article uses a skydome. My scene is different - I don't render a whole earth with an atmosphere which can be also visible from the space but some finite flat (rectangle) area with objects, for example a race track. In fact this is the most common scenario in many games. Now I wonder how to render a sky in such case:

1.What kind of geometry I should use: skydome, skybox or a full screen quad - then I have to move almost all calculations to the fragment shader, but I don't know if it makse sense in terms quality/performance ?

2.How to place sky geometry on the scene ? My idea: I have a hemisphere (skydome) geometry with radius = 1 and center in vec3(0, 0, 0) - in object space. Those vertices are sent to the atmospheric scattering vertex shader:

layout(location=0) in vec3 inPosition;

Next, In the vertex shader I transform vertex this way:

v3Pos = inPosition * 0.25f + 10.0f;

Uniform v3CameraPos = vec3(0.0f, 10.0f, 0.0f), uniform fInnerRadius = 10.0f, uniform fCameraHeight = 10.0f

Then I have correct an inner/outer radius propotion (10/10.25),right? I also send to the vertex shader a model matrix which sets a position of the hemisphere to the postion of the mobile camera vec3(myCamera.x, myCamera.y, myCamera.z):

vec4 position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(inPosition, 1.0);
gl_Position = position.xyww; // always fails depth test.

The hemisphere moves together with the camera (encloses only some space around camera with radius = 1, but it also always fails a depth test.)

Unfortunately a sky color which I get is not correct: screen1

3.What about a "sky curve"? Here is a picture which demonstrate what I mean: image1 How should I set a sky curve ?

Edit1 - debugging: In the vertex shader I assigned to v3Pos position of the "highest" vertex in the hemisphere:

vec3 v3Pos = vec3(0.0f, 10.25f, 0.0f);

Now the whole sky contains a color of that vertex: screen2

Upvotes: 0

Views: 5656

Answers (2)

Spektre
Spektre

Reputation: 51835

here is my simplified atmosphere scattering

work for both in outside and inside atmosphere

  1. For realistic scattering You need to compute the curve integral through atmosphere depth

    so you need to know how thick is atmosphere in which direction. Your terrain is 'flat QUAD +/- some bumps' but you must know where on Earth it is position (x,y,z) and normal (nx,ny,nz). For atmosphere you can use sphere or like me ellipsoid unless you want implement the whole scattering (integration through area not curve) process then what you really need is just the ray length from your camera to end of atmosphere.

    so you can also do a cube-map texture with precomputed atmosphere edge distance because the movement inside your flat area does not matter much.

  2. You also need the Sun position

    can be simplified to just rotating normal around earth axis 1 round per day or you can also implement the season trajectory shift

  3. Now just before rendering fill screen with sky

    You can do it all inside shaders. one Quad is enough.

    in fragment: get the atmosphere thickness form cube-map or from pixel direction intersection with atmosphere sphere/ellipsoid and then do the integration (full or simplified). Output the color to screen pixel

Upvotes: 2

bjorke
bjorke

Reputation: 3305

It really doesn't matter what geometry you use as long as (a) it covers the scren and (b) you feed the fragment shader a reasonable value for v3Direction. For all cases is a typical on-the-earth game like one with a race track, the sky will be behind all other objects, so accurate Z is not such a big deal.

Upvotes: 0

Related Questions