#ifdef MOSS_NOISE
    vec3 mossColor = mix(vec3(0.2745, 0.3412, 0.1412), vec3(0.451, 0.5804, 0.1255), float(hash33(floor(mod(worldPos, vec3(100.0)) * MOSS_SIZE + 0.03) * MOSS_SIZE)) * 0.15);
    #if MOSS_IN_CAVES < 2
        bool disableLight = true;
    #else
        bool disableLight = false;
    #endif

    #if MOSS_SIDE_INTENSITY == 0
        float mossSide = 0.0;
    #else
        float mossSide = MOSS_SIDE_INTENSITY * 0.1;
    #endif

    vec2 mossVec = getOverlayNoise(mossSide, disableLight, false, 0.1, MOSS_SIZE, worldPos, MOSS_TRANSPARENCY, MOSS_NOISE_REMOVE_INTENSITY * 1.5);

    float mossNoise = mossVec.y;
    float mossVariable = mossVec.x;

    #if MOSS_IN_CAVES == 0
        mossVariable *= inLushCave;
    #endif

    mossColor *= 1.1;
    mossColor += 0.13 * mossNoise * MOSS_NOISE_INTENSITY; // make the noise less noticeable & configurable with option

    #ifdef GBUFFERS_TERRAIN
        #if MOSS_IN_CAVES == 0
            emission *= mix(1.0, overlayNoiseEmission, inLushCave * overlayNoiseIntensity * mossNoiseIntensity);
            smoothnessG = mix(smoothnessG, 0.0, mossVariable * inLushCave * overlayNoiseIntensity * mossNoiseIntensity);
            smoothnessD = mix(smoothnessD, smoothnessG, mossVariable * inLushCave * overlayNoiseIntensity * mossNoiseIntensity);
        #else
            emission *= mix(1.0, overlayNoiseEmission, overlayNoiseIntensity * mossNoiseIntensity);
            smoothnessG = mix(smoothnessG, 0.0, mossVariable * overlayNoiseIntensity * mossNoiseIntensity);
            smoothnessD = mix(smoothnessD, smoothnessG, mossVariable * overlayNoiseIntensity * mossNoiseIntensity);
        #endif
    #endif

    #if MOSS_IN_CAVES == 0
        smoothnessG = mix(smoothnessG, max(smoothnessG, 0.3 * color.g * float(color.g > color.b * 1.5)), mossVariable * inLushCave * overlayNoiseIntensity * mossNoiseIntensity);
    #else
        smoothnessG = mix(smoothnessG, max(smoothnessG, 0.3 * color.g * float(color.g > color.b * 1.5)), mossVariable * overlayNoiseIntensity * mossNoiseIntensity);
    #endif

    #ifdef GBUFFERS_WATER
            #if MOSS_IN_CAVES == 0
                overlayNoiseTransparentOverwrite = mix(overlayNoiseTransparentOverwrite, overlayNoiseAlpha, inLushCave);
                fresnel = mix(fresnel, 0.01, mossVariable * overlayNoiseFresnelMult * inLushCave);
            #else
                overlayNoiseTransparentOverwrite = overlayNoiseAlpha;
                fresnel = mix(fresnel, 0.01, mossVariable * overlayNoiseFresnelMult);
            #endif
    #endif

    color.rgb = mix(color.rgb, mossColor, mossVariable * overlayNoiseIntensity * mossNoiseIntensity);
    color.a = mix(color.a, 1.0, clamp(overlayNoiseTransparentOverwrite * mossVariable * mossNoiseIntensity, 0.0, 1.0));
#endif

#ifdef SAND_NOISE
    #if SAND_CONDITION == 0
        float desertSandColorMixer = inSand + inRedSand;
        vec3 sandColor = mix(
            vec3(0.9216, 0.8353, 0.6196), (inSand * vec3(0.9216, 0.8353, 0.6196) + inRedSand * vec3(0.5843, 0.3412, 0.1569)), desertSandColorMixer);
    #else
        vec3 sandColor = vec3(0.9216, 0.8353, 0.6196);
    #endif

    #if SAND_SIDE_INTENSITY == 0
        float sandSide = 0.0;
    #else
        float sandSide = SAND_SIDE_INTENSITY * 0.1;
    #endif

    vec2 sandVec = getOverlayNoise(sandSide, SAND_IN_CAVES, true, 0.1, SAND_SIZE, worldPos, SAND_TRANSPARENCY, SAND_NOISE_REMOVE_INTENSITY * 2.0);

    float sandNoise = sandVec.y;
    float sandVariable = sandVec.x;

    #if SAND_CONDITION == 0
        sandVariable *= desertSandColorMixer;
    #elif SAND_CONDITION == 1
        sandVariable *= inDry;
    #endif

    sandColor *= 1.1;
    sandColor += 0.13 * sandNoise * SAND_NOISE_INTENSITY; // make the noise less noticeable & configurable with option

    #ifdef GBUFFERS_TERRAIN
        #if SAND_CONDITION == 0
            emission *= mix(1.0, overlayNoiseEmission, desertSandColorMixer * overlayNoiseIntensity * sandNoiseIntensity);
            smoothnessG = mix(smoothnessG, pow(color.g, 16.0) * 2.0, sandVariable * desertSandColorMixer * overlayNoiseIntensity * sandNoiseIntensity);
            smoothnessG = mix(smoothnessG, min1(smoothnessG), sandVariable * desertSandColorMixer * overlayNoiseIntensity * sandNoiseIntensity);
            smoothnessD = mix(smoothnessD, smoothnessG * 0.7, sandVariable * desertSandColorMixer * overlayNoiseIntensity * sandNoiseIntensity);
            highlightMult = mix(highlightMult, 2.0, sandVariable * desertSandColorMixer * overlayNoiseIntensity * sandNoiseIntensity);
        #elif SAND_CONDITION == 1
            emission *= mix(1.0, overlayNoiseEmission, inDry * overlayNoiseIntensity * sandNoiseIntensity);
            smoothnessG = mix(smoothnessG, pow(color.g, 16.0) * 2.0, sandVariable * inDry * overlayNoiseIntensity * sandNoiseIntensity);
            smoothnessG = mix(smoothnessG, min1(smoothnessG), sandVariable * inDry * overlayNoiseIntensity * sandNoiseIntensity);
            smoothnessD = mix(smoothnessD, smoothnessG * 0.7, sandVariable * inDry * overlayNoiseIntensity * sandNoiseIntensity);
            highlightMult = mix(highlightMult, 2.0, sandVariable * inDry * overlayNoiseIntensity * sandNoiseIntensity);
        #else
            emission *= overlayNoiseEmission;
            smoothnessG = mix(smoothnessG, pow(color.g, 16.0) * 2.0, sandVariable * overlayNoiseIntensity * sandNoiseIntensity);
            smoothnessG = mix(smoothnessG, min1(smoothnessG), sandVariable * overlayNoiseIntensity * sandNoiseIntensity);
            smoothnessD = mix(smoothnessD, smoothnessG * 0.7, sandVariable * overlayNoiseIntensity * sandNoiseIntensity);
            highlightMult = mix(highlightMult, 2.0, sandVariable * overlayNoiseIntensity * sandNoiseIntensity);
        #endif
    #endif

    #ifdef GBUFFERS_WATER
        #if SAND_CONDITION == 0
            overlayNoiseTransparentOverwrite = mix(0.0, overlayNoiseAlpha, desertSandColorMixer);
            fresnel = mix(fresnel, 0.01, sandVariable * overlayNoiseFresnelMult * desertSandColorMixer);
        #elif SAND_CONDITION == 1
            overlayNoiseTransparentOverwrite = mix(0.0, overlayNoiseAlpha, inDry);
            fresnel = mix(fresnel, 0.01, sandVariable * overlayNoiseFresnelMult * inDry);
        #else
            overlayNoiseTransparentOverwrite = overlayNoiseAlpha;
            fresnel = mix(fresnel, 0.01, sandVariable * overlayNoiseFresnelMult);
        #endif
    #endif

    color.rgb = mix(color.rgb, sandColor, sandVariable * overlayNoiseIntensity * sandNoiseIntensity);
    color.a = mix(color.a, 1.0, clamp(overlayNoiseTransparentOverwrite * sandVariable * overlayNoiseIntensity * sandNoiseIntensity, 0.0, 1.0));
#endif