float vc_lD(in vec3 rPos, const int steps) {
    float density       = 0.053*(1.0-rainStrength*0.9);

    #ifdef isReflectPass
        density *= 0.6;
    #endif

    //density *= 1.0-wetness*0.25;

    float stepSizeMod   = 1.0-(linStep(rPos.y, vc_lowEdge, vc_highEdge)*0.97)*(timeNoon);
    vec3 dir            = mix(vec.light, vec.up, timeLightTransition);
        dir             = normalize(mat3(gbufferModelViewInverse)*dir);
    float stepSize      = (vc_depth/steps)*stepSizeMod;
    vec3 rayStep        = dir*stepSize;

    #ifdef isComposite0
        #ifdef s_vcLightHQsample
            rPos       += rayStep*bayer64s;
        #else
            rPos       += rayStep;
        #endif
    #else
        rPos           += rayStep;
    #endif
    
    float transmittance = 0.0;

    for (int i = 0; i<steps; i++) {
        float cloudMap  = vc_getCloudMap(rPos);

        #ifdef debugCLOUDS
            if (cloudMap <= 0.0) returnCol = mix(returnCol, vec3(1.0, 0.0, 0.0)*30, 1.0/steps);
        #endif

        if (cloudMap>0.0) transmittance  += vc_shape(rPos, cloudMap)*stepSizeMod;
        rPos           += rayStep;
    }
    return transmittance*density*stepSize;
}
float vc_lDsky(in vec3 rPos, const int steps) {
    float density       = 0.0006;

    //density *= 1.0-wetness*0.25;

    //float stepSizeMod   = 1.0-(linStep(rPos.y, vc_lowEdge, vc_highEdge)*0.97)*(timeNoon);
    vec3 dir            = vec.up;
        dir             = normalize(mat3(gbufferModelViewInverse)*dir);
    float stepSize      = (vc_depth/steps);
    vec3 rayStep        = dir*stepSize;

        rPos           += rayStep;
    
    float transmittance = 0.0;

    for (int i = 0; i<steps; i++) {
        float cloudMap  = vc_getCloudMap(rPos);

        if (cloudMap>0.0) transmittance  += vc_shape(rPos, cloudMap);
        rPos           += rayStep;
    }
    return transmittance*density*stepSize;
}
float vc_lDskyFast(in vec3 rPos) {
    float density       = 0.0002;

    vec3 dir            = vec.up;
        dir             = normalize(mat3(gbufferModelViewInverse)*dir);
    float stepSize      = (vc_depth/2);
    vec3 rayStep        = dir*stepSize;
        rPos           += rayStep;
    
    float transmittance = 0.0;

    float cloudMap  = vc_getCloudMap(rPos);

    if (cloudMap>0.0) transmittance  += vc_shape(rPos, cloudMap);

    return transmittance*density*stepSize;
}

float vc_getScatter(in float oD, in float lD, in float powder, in float phaseMod, in float lDmod, in float vDotL) {
    float transmittance = exp2(-lD*lDmod);
    float inscatter     = exp2(-oD*lDmod*0.1);
    float phase         = c_miePhase(vDotL*phaseMod)*0.93+0.07;
        phase           = mix(phase, 1.0, rainStrength*0.1);

    return max(powder*phase*transmittance, inscatter*0.025*(phase*0.5+0.5));
}
float vc_getScatterLQ(in float oD, in float lD, in float powder, in float vDotL) {
    float transmittance = exp2(-lD);
    float phase         = c_miePhase(vDotL)*0.9+0.1;

    return max(powder*phase*transmittance, 0.0);
}

float vc_getSkylight(in float oD, in vec3 rPos) {
    float lD            = vc_lDskyFast(rPos);
    float transmittance = exp2(-lD);

    return transmittance;
}

void vc_scatterLQ(inout float scatter, in float oD, in vec3 rayPos, in float scatterCoeff, in float vDotL, in float transmittance, in float stepTransmittance, in float cloudMap) {
    float lD            = vc_lD(rayPos, 3)*0.4;
    float powder        = 1.0-exp2(-oD*2.0);
        powder          = mix(powder, 1.0, vDotL*0.5+0.5);
    float scatterInt    = scatterIntegral(stepTransmittance, 1.11);
    float beerPowderFake = 1.0-exp2(-oD*0.05)*0.5;

    float tempScatter   = vc_getScatterLQ(oD, lD, powder*beerPowderFake, vDotL)*scatterCoeff*scatterInt*transmittance;

    scatter += tempScatter*2.0;
}

#ifdef isComposite0
void vc_scatter(inout vec2 scatter, in float oD, in vec3 rayPos, in float scatterCoeff, in float vDotL, in float transmittance, in float stepTransmittance, in float cloudMap) {
    float lD            = vc_lD(rayPos, s_vcLightSamples)*0.45;
    float powder        = 1.0-exp2(-oD*2.0);
        powder          = mix(powder, 1.0, vDotL*0.4+0.6);
    float scatterInt    = scatterIntegral(stepTransmittance, 1.11);
    float beerPowderFake = 1.0-exp2(-oD*0.06)*0.5;

    float tempScatter   = vc_getScatter(oD, lD, powder*beerPowderFake, 1.0, 1.0, vDotL)*scatterCoeff*scatterInt*transmittance;

    scatter.x += tempScatter*2.0;

    #ifdef s_skylightScatter
        float skylight      = vc_getSkylight(oD, rayPos);
        scatter.y += skylight*scatterInt*transmittance;
    #endif
}
#else
void vc_scatter(inout float scatter, in float oD, in vec3 rayPos, in float scatterCoeff, in float vDotL, in float transmittance, in float stepTransmittance, in float cloudMap) {
    float lD            = vc_lD(rayPos, s_vcLightSamples)*0.45;
    float powder        = 1.0-exp2(-oD*2.0);
        powder          = mix(powder, 1.0, vDotL*0.4+0.6);
    float scatterInt    = scatterIntegral(stepTransmittance, 1.11);
    float beerPowderFake = 1.0-exp2(-oD*0.06)*0.5;

    float tempScatter   = vc_getScatter(oD, lD, powder*beerPowderFake, 1.0, 1.0, vDotL)*scatterCoeff*scatterInt*transmittance;

    scatter += tempScatter*2.0;
}
#endif

#if (defined isComposite0 && s_vcLightingQuality==2) 
void vc_multiscatter(inout vec2 scatter, in float oD, in vec3 rayPos, in float scatterCoeff, in float vDotL, in float transmittance, in float stepTransmittance, in float cloudMap) {
    float tempScatter   = 0.0;
    float lD            = vc_lD(rayPos, s_vcLightSamples)*1.1;
    float powder        = 1.0-exp2(-oD*2.0);
        powder          = mix(powder, 1.0, vDotL*0.4+0.6);
    float scatterInt    = scatterIntegral(stepTransmittance, 1.11);
    float beerPowderFake = 1.0-exp2(-oD*0.06)*0.5;
        
    for (int i = 0; i<vc_msQuality; i++) {

        float scatterMod = pow(0.5, float(i));
        float lDmod = pow(0.15, float(i));
        float phaseMod = pow(0.85, float(i));

        scatterCoeff *= scatterMod;

        tempScatter += vc_getScatter(oD, lD, powder*beerPowderFake, phaseMod, lDmod, vDotL)*scatterCoeff*scatterInt;
    }
    scatter.x += tempScatter*transmittance*1.66;

    #ifdef s_skylightScatter
        float skylight      = vc_getSkylight(oD, rayPos);
        scatter.y += skylight*scatterInt*transmittance;
    #endif
}
#endif