0
votes

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

2
This is not related to your actual problem, but it did stick out to me immediately. You should consider declaring inPosition as vec4. GLSL will automatically expand any vertex attribute using (0.0, 0.0, 0.0, 1.0) for missing components. So if you declare it vec4 and only give it enough data to fill a vec3 when you use glVertexAttribPointer (...), GLSL will automatically assign inPosition.w a value of 1.0 and then you do not have to mess with stuff like vec4 (inPosition, 1.0) in your vertex shader. This only works for vertex attributes, by the way.Andon M. Coleman
@Irbis how it goes with your problem? what way did you go and with what results?Spektre

2 Answers

1
votes

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

0
votes

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.