# Atmospheric scattering (preetham)

This topic is 4588 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello, I'm trying to implement the atmospheric scattering method described by preetham here or here. While I have something that looks somewhat like what I would expect the final result to look like, there are still several things that are clearly wrong. The sun is tinted teal, there is no sunset effect when I move the light near the horizon, and the opposite side of the skysphere is less bright than around the sun, but more bright than the rest of the sky. I'm sure that all of these problems are from my misunderstanding of some part of the theory, but other than the way I'm separating calculations for each of the wavelengths I don't see what I'm missing. Here is the shader source:
float4x4 worldViewProj  : WORLDVIEWPROJECTION;
float4x4 world            : WORLD;
float3   camPos;            // The camera's position
float3   sunVec;            // The sun's direction

const float3    invWaveLength4 = {5.602045, 9.473285, 19.643818}; // 1 / (wavelength^4) for each channel
const float        Br = 0.0025;
const float        Bm = 0.001;
const float        Esun = 1.0;
const float        g = 0.80;

struct SkyDomeOutput
{
float4 position : POSITION;
float3 inscattering : TEXCOORD0;
};

SkyDomeOutput VS_SkyDomePass(float4 position : POSITION)
{
float3 worldpos = mul(position, world).xyz;
float3 viewDir = worldpos - camPos;
float distFromCamToVert = length(viewDir);
viewDir /= distFromCamToVert;
sunVec = normalize(sunVec);
float costheta = dot(viewDir, sunVec);

float BrTheta = (3.0 / (16.0 * 3.14159)) * Br * (1 + costheta*costheta);
float BmTheta = (1.0 / (4.0 * 3.14159)) * Bm * ( (1 - g)*(1 - g) / pow(1 + g*g - 2*g*costheta, 3.0/2.0) );
float extinction = exp(-(Br + Bm) * distFromCamToVert);
float inscattering = (BrTheta + BmTheta) / (Br + Bm) * Esun * (1 - extinction);

SkyDomeOutput sdo;
sdo.position = mul(position, worldViewProj);
sdo.inscattering = invWaveLength4 * inscattering;

return sdo;
}

float4 PS_SkyDomePass(float3 inscattering : TEXCOORD0) : COLOR
{
return float4(inscattering.xyz, 1.0);
}


Here are a few screenshots that might help diagnose the problem. The jpg compression and the shrinking mess the image up a decent amount, but you can still see what I think you need to see. Image of the sun with the shader set as above. An image where you can see from the sun to the horizon. (The scattering has not yet been applied to the terrain) Image of the sun with the inscattering multiplied by float3(5.0, 5.0, 5.0) rather than invWaveLength4 If anyone has an idea about what I'm doing wrong I'd appreciate the help. As usual, thanks in advance for your help. P.S. Please, no comments about the (lack of) naming convention or the terrain erosion. I know they suck, thank you. =)

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 13
• 9
• 15
• 14
• 46
• ### Forum Statistics

• Total Topics
634067
• Total Posts
3015323
×