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
inPosition
asvec4
. GLSL will automatically expand any vertex attribute using (0.0, 0.0, 0.0, 1.0) for missing components. So if you declare itvec4
and only give it enough data to fill avec3
when you useglVertexAttribPointer (...)
, GLSL will automatically assigninPosition.w
a value of 1.0 and then you do not have to mess with stuff likevec4 (inPosition, 1.0)
in your vertex shader. This only works for vertex attributes, by the way. – Andon M. Coleman