Atmospheric scattering sky from space artifacts
- by ollipekka
I am in the process of implementing atmospheric scattering of a planets from space. I have been using Sean O'Neil's shaders from http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html as a starting point.
I have pretty much the same problem related to fCameraAngle except with SkyFromSpace shader as opposed to GroundFromSpace shader as here:
http://www.gamedev.net/topic/621187-sean-oneils-atmospheric-scattering/
I get strange artifacts with sky from space shader when not using fCameraAngle = 1 in the inner loop. What is the cause of these artifacts? The artifacts disappear when fCameraAngle is limtied to 1. I also seem to lack the hue that is present in O'Neil's sandbox (http://sponeil.net/downloads.htm)
Camera position X=0, Y=0, Z=500. GroundFromSpace on the left, SkyFromSpace on the right.
Camera position X=500, Y=500, Z=500. GroundFromSpace on the left, SkyFromSpace on the right.
I've found that the camera angle seems to handled very differently depending the source:
In the original shaders the camera angle in SkyFromSpaceShader is calculated as:
float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
Whereas in ground from space shader the camera angle is calculated as:
float fCameraAngle = dot(-v3Ray, v3Pos) / length(v3Pos);
However, various sources online tinker with negating the ray. Why is this?
Here is a C# Windows.Forms project that demonstrates the problem and that I've used to generate the images:
https://github.com/ollipekka/AtmosphericScatteringTest/
Update: I have found out from the ScatterCPU project found on O'Neil's site that the camera ray is negated when the camera is above the point being shaded so that the scattering is calculated from point to the camera.
Changing the ray direction indeed does remove artifacts, but introduces other problems as illustrated here:
Furthermore, in the ScatterCPU project, O'Neil guards against situations where optical depth for light is less than zero:
float fLightDepth = Scale(fLightAngle, fScaleDepth);
if (fLightDepth < float.Epsilon)
{
continue;
}
As pointed out in the comments, along with these new artifacts this still leaves the question, what is wrong with the images where camera is positioned at 500, 500, 500? It feels like the halo is focused on completely wrong part of the planet. One would expect that the light would be closer to the spot where the sun should hits the planet, rather than where it changes from day to night.
The github project has been updated to reflect changes in this update.