# Pre-Computed Atmospheric Scattering - Transmittance Table

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

## Recommended Posts

Hello,

I am currently working on Eric Bruneton's pre-computed atmospheric scattering. I have been trying to figure out what was wrong with my irradiance1 texture so I decided to render the transmittance table to screen and this was the result:

Which looks quite different from what it is supposed to be:

I am confused since I am basically copying Brunetons/Neyret's code verbatim...

Here is my fragment shader for reference:

const float Rg = 6360.0;
const float Rt = 6420.0;
const float RL = 6421.0;

float limit(float r, float mu) {
float dout = -r * mu + sqrt(r * r * (mu * mu - 1.0) + RL * RL);
float delta2 = r * r * (mu * mu - 1.0) + Rg * Rg;
if (delta2 >= 0.0) {
float din = -r * mu - sqrt(delta2);
if (din >= 0.0) {
dout = min(dout, din);
}
}
return dout;
}

void getTransmittanceRMu(out float r, out float muS) {
r = gl_FragCoord.y / 64.0;
muS = gl_FragCoord.x / 256.0;

r = Rg + r * (Rt - Rg);
muS = -0.15 + muS * (1.0 + 0.15);

}

const int TRANSMITTANCE_INTEGRAL_SAMPLES = 500;

float opticalDepth(float H, float r, float mu) {
float result = 0.0;
float dx = limit(r, mu) / float(TRANSMITTANCE_INTEGRAL_SAMPLES);
float xi = 0.0;
float yi = exp(-(r - Rg) / H);
for (int i = 1; i <= TRANSMITTANCE_INTEGRAL_SAMPLES; ++i) {
float xj = float(i) * dx;
float yj = exp(-(sqrt(r * r + xj * xj + 2.0 * xj * r * mu) - Rg) / H);
result += (yi + yj) / 2.0 * dx;
xi = xj;
yi = yj;
}
return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? 1e9 : result;
}

void main() {
float HR = 8.0;
float HM = 12.0;
vec3 betaR = vec3(5.8e-3, 1.35e-2, 3.31e-2);
vec3 betaMSca = vec3(4e-3);
vec3 betaMEx = betaMSca / 0.9;
float r, muS;
getTransmittanceRMu(r, muS);
vec3 depth = betaR * opticalDepth(HR, r, muS) + betaMEx * opticalDepth(HM, r, muS);
gl_FragColor = vec4(exp(-depth), 0.0); // Eq (5)

}



Any help would be appreciated...thanks

Edited by multifractal

##### Share on other sites

I was banging my head against this as well and just solved it.  So there are four issues really.

First of all, that image you're comparing against is squashed horizontally.  The actual transmittance table is a 256x64 texture, and should look like this:

Second, your texture is upside down.  I know because I generated the same one at first.  Swap the Y coordinate.

Third, your colors look washed out because you are using an HM value of 12.  It should be 1.2

And Fourth, in the Bruneton code he defines "TRANSMITTANCE_NON_LINEAR" (in the common.glsl file).  You are using the code from the else clause of this, which indeed results in the curve you are seeing.  With the code from the #ifdef TRANSMITTANCE_NON_LINEAR block, you get the correct curve.  The difference is in the last two lines of your getTransmittanceRMu function;  instead of this:

r = Rg + r * (Rt - Rg);

muS = -0.15 + muS * (1.0 + 0.15);

you want to do this

r = Rg + (r * r) * (Rt - Rg);

muS = -0.15 + tan(1.5 * muS) / tan(1.5) * (1.0 + 0.15);

:

Wow, thank you so much! This is really fantastic. Your help is greatly appreciated.

• 11
• 9
• 17
• 13
• 11