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 makes 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:


  1. What about a "sky curve"? Here is a picture which demonstrate what I mean:


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

  • 3
    \$\begingroup\$ I think your question is lost between debugging your current code, and suggestions of what to do. Maybe rephrasing your question could help you get better answers. \$\endgroup\$
    – concept3d
    Commented Nov 26, 2013 at 5:59

2 Answers 2


You need to pass your tuning values through uniform data, and not vertex data.

Vertex data always complexify export pipeline, and binding (input signature).

I recommend a screen quad for the support geometry of the sky, and render it at the end of your frame, when all other objects are rendered, using a depth test operation that is supposed to fail all tests, so that only wholes are rendered. (you can use a special orthographic camera matrix for that, where you know that 1 is the deepest value, and you put your screen quad at 0.99 to avoid far clipping, for still to fail all depth tests.)

Then it will be optimal in performance, it is a classic defered rendering technique. (unfortunately with the classic antialiasing problems that we know)

You can also use a skycube or a skysphere, companies have happened to use the 3 techniques described above, so its not like there is a universal answer.

  • \$\begingroup\$ All tuning values are passed through uniform data. You are wrong about a sky geometry for that scattering algorithm. See here: gamedev.net/topic/… \$\endgroup\$
    – Irbis
    Commented Dec 21, 2013 at 20:31

I haven't worked on this problem personally so I probably missed a lot of the nuances but I have managed a project where we implemented just this sort of scattering model. We actually did this twice, once for a forward rendered pipeline and again for a deferred lighting pipeline. In both cases we did everything in screen space with what little dynamic data we needed uploaded as shader constants, and the static data pre-calculated and encoded into 3d textures. The forward version was done as a post process step (although this caused all sorts of headaches, especially lighting alpha polys that were not represented in the depth buffer). In the deferred lighting setup we did this as part of the lighting pass with far fewer problems.

Sorry for being a bit vague but hopefully at least of some help.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .