Jump to content
  • Advertisement
Sign in to follow this  
multifractal

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.

If you intended to correct an error in the post then please contact us.

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:

 

Screen_Shot_2013_09_07_at_2_33_49_PM.png

 

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

 

Untitled.png

 

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 this post


Link to post
Share on other sites
Advertisement

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:

 

xwdOZEj.jpg

 

 

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. 

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!