Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

atmospheric scattering and sky geometry

Started by Irbis_88 Nov 29, 2013 at 10:06 PM 2 replies 4.9k views
Original Post
Irbis_88
Irbis_88

I'm trying to implement an atmospheric scattering in my graphics (game) engine based on the gpu gems article: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html 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: http://img17.imageshack.us/img17/6930/un5u.png

3.What about a "sky curve"? Here is a picture which demonstrate what I mean: http://imageshack.us/a/img5/4968/fccw.png

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: http://img27.imageshack.us/img27/7241/a6ud.png

Kaptein
Kaptein

That's the article that shows an implentation of simulated Rayleigh scattering, and it requires a skydome to be the top part of basically a planet's atmosphere.

The skydome must be created as in the drawing shown:

http://http.developer.nvidia.com/GPUGems2/elementLinks/16_atmospheric_03.jpg

I have an implementation that works here:

https://github.com/fwsGonzo/cppcraft/blob/master/source/atmosphere.cpp

Some downsides:

1. I still haven't bothered to index the dome.

2. His implementation of scattering isn't the best

3. It doesn't work well if your player can go up/down, as in flying (but that isn't unusual at all)

Otherwise, it's fairly ok

ankhd
ankhd

Heres a good read

Irbis_88
Irbis_88

ankhd - thank you for the link but I didn't found there informations about a sky geometry. I think that there is also used skydome which is the same as in the GPU Gems 2 article . Please let me know if I wrong.

Kaptein - thank you for sharing the code. First I generated a mesh with innerRadius = 10 and outerRadius = 10,25. It looks very flat compared to the hemisphere:

http://imageshack.us/a/img189/223/yn8w.png

http://imageshack.us/a/img11/6931/zcdv.png

When I use above mesh I get correct results. I attached that skydome to the camera as I described in the first post. I also tried another approach: I generated a mesh with innerRadius = 100000 and outer radius = 102500. Then camera height can be variable. Here are screens:

cameraHeight = innerRadius (100000): http://imageshack.us/a/img713/9215/fmx1.png

cameraHeight = 101250: http://imageshack.us/a/img560/3236/k5fp.png As you can see there a little mismatch between a sun and a brighter area on the sky which should be around the sun. Is it possible to fix that ?

Moreover I removed the last line


gl_FragColor.a = gl_FragColor.b;

from the SkyFromAtmosphere.frag and a sky color is more realistic.

Conslusion: a hemisphere as a sky geometry doesn't work with that algorithm.

Which atmospheric scattering algorithm do you use in your implementations ? How you represent a sky geometry ? How it is done in games ? (There can be some differences between the "standard scenes" and the "flight simulators scenes")

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.