I implemented a simulation for the colour of the sky a while ago by following the scratch a pixel tutorial: https://www.scratchapixel.com/lessons/procedural-generation-virtual-worlds/simulating-sky

I adapted it for the actual sun position and am able to get realistic sky colours during the day. However, I noticed that after sunset/ before sunrise, the colours are greyish when they should be deep blue. After researching about this, I read that this is due to the ozone absorption not being present in my model.

I used extinction coefficients : (3.426,8.298,0.356) * 0.06e-5 -> found on https://media.contentapi.ea.com/content/dam/eacom/frostbite/files/s2016-pbs-frostbite-sky-clouds-new.pdf

and also read that since the ozone does not scatter, it should only be added to the transmittance value.

more info about ozone

Therefore, I modified the code from scratchapixel as follows:

        for (uint32_t i = 0; i < numSamples; ++i) {
            vec3 samplePosition = ray_in2.origin() + (tCurrent + 
            segmentLength * 0.5f) * ray_in2.direction();
            float height = samplePosition.length() - atmosphere.earthRadius;

            // compute optical depth for light
            float hr = exp(-height / atmosphere.Hr) * segmentLength;
            float hm = exp(-height / atmosphere.Hm) * segmentLength;
            float ho = exp(-height / atmosphere.Hr)* segmentLength*(6e-7);
            opticalDepthR += hr;
            opticalDepthM += hm;
            opticalDepthO += ho;

            // light optical depth
            float t0Light, t1Light;

            for (j = 0; j < numSamplesLight; ++j) {
                vec3 samplePositionLight = samplePosition + (tCurrentLight + 
                segmentLengthLight * 0.5f) * sunDir;
                float heightLight = samplePositionLight.length() - 

                if (heightLight < 0) break;
                opticalDepthLightR += exp(-heightLight / atmosphere.Hr) * 
                opticalDepthLightM += exp(-heightLight / atmosphere.Hm) * 
                opticalDepthLightO += exp(-heightLight / atmosphere.Hr) * 
                segmentLengthLight*(6e-7); ;
                tCurrentLight += segmentLengthLight;
            if (j == numSamplesLight) {
                vec3 tau = (betaR) * (opticalDepthR + opticalDepthLightR) + 
               betaM * 1.1f * (opticalDepthM + opticalDepthLightM)+ betaO*
              (opticalDepthO + opticalDepthLightO);
                vec3 attenuation(exp(-tau.x()), exp(-tau.y()), exp(-

summary : -I added variable opticalDepthO and opticalDepthLightO which are calculated same as the optical depth for Rayleigh, but multiplied by 6e-7.

-Then, the sum of opticalDepthLightO and opticalDepthO is multiplied by the extiction coefficient for ozone and added to variable tau.

Problem is, I see no difference in my sky colour before and after adding ozone. Can someone guide me to what it is that I'm doing wrong? Thanks in advance!


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.