float lc_lD(in vec3 rPos, const int steps) {
    float density       = 0.006*(1.0-rainStrength*0.9);
    vec3 dir            = mix(vec.light, vec.up, timeLightTransition);
        dir             = normalize(mat3(gbufferModelViewInverse)*dir);
    float stepSizeMod   = 1.0-(linStep(rPos.y, lc_lowEdge, lc_highEdge)*0.95)*(timeNoon);
    float stepSize      = (lc_depth/steps)*stepSizeMod;
    vec3 rayStep        = dir*stepSize;

    #ifdef isComposite0
        #ifdef s_lcLightHQsample
            rPos       += rayStep*bayer64s;
        #else
            rPos       += rayStep;
        #endif
    #else
        rPos           += rayStep;
    #endif

    float transmittance = 0.0;

    for (int i = 0; i<steps; i++) {
        transmittance  += lc_shape(rPos, true)*stepSizeMod;
        rPos           += rayStep;
    }
    return transmittance*density*stepSize;
}
float lc_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 lc_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);
    float phase         = c_miePhase(vDotL*phaseMod)*0.9+0.1;

    return max(powder*phase*transmittance, inscatter*0.06*(phase*0.5+0.5));
}
void lc_scatterLQ(inout float scatter, in float oD, in vec3 rayPos, in float scatterCoeff, in float vDotL, in float transmittance, in float stepTransmittance) {
    float lD            = lc_lD(rayPos, 3)*1.1;
    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 tempScatter   = lc_getScatterLQ(oD, lD, powder, vDotL)*scatterCoeff*scatterInt*transmittance;

    scatter += tempScatter*2.0;
}
void lc_scatter(inout float scatter, in float oD, in vec3 rayPos, in float scatterCoeff, in float vDotL, in float transmittance, in float stepTransmittance) {
    float lD            = lc_lD(rayPos, 4);
    float powder        = 1.0-exp2(-oD);
        powder          = mix(powder, 1.0, vDotL*0.5+0.5);
    float scatterInt    = scatterIntegral(stepTransmittance, 1.11);
    float beerPowderFake = 1.0-exp2(-oD*0.0125)*0.35;

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

    scatter += tempScatter*2.0;
}
void lc_multiscatter(inout float scatter, in float oD, in vec3 rayPos, in float scatterCoeff, in float vDotL, in float transmittance, in float stepTransmittance) {
    float tempScatter   = 0.0;
    float lD            = lc_lD(rayPos, 4)*1.1;
    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.0125)*0.35;
        
    for (int i = 0; i<lc_msQuality; i++) {

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

        scatterCoeff *= scatterMod;

        tempScatter += lc_getScatter(oD, lD, powder*beerPowderFake, phaseMod, lDmod, vDotL)*scatterCoeff*scatterInt*transmittance;
    }
    scatter += tempScatter*2.0;
}