declare const _default: "\n    #include \"screenDepthPS\"\n\n    varying uv0: vec2f;\n\n    uniform uFogCameraPos: vec3f;\n    uniform uFogCameraFwd: vec3f;\n    uniform uFogInvView: mat4x4f;\n    uniform uFogProjScale: vec2f;\n    uniform uFogTint: vec3f;\n    uniform uFogLightColor: vec3f;\n    uniform uFogLightDir: vec3f;      // world space direction towards the light\n    uniform uFogAmbient: vec3f;\n    uniform uFogParams: vec4f;        // x: density, y: height base, z: height falloff, w: max distance\n    uniform uFogScatterParams: vec4f; // x: anisotropy, y: step count, z: temporal noise offset, w: shadow intensity\n\n    #ifdef FOG_SHADOWS\n        uniform uFogShadowMatrixPalette: array<mat4x4f, 4>;\n        uniform uFogShadowCascadeDistances: vec4f;\n        uniform uFogShadowParams: vec4f; // x: cascade count, y: bias, z: unused, w: max shadow distance\n        #ifdef FOG_SHADOW_PCF\n            var uFogShadowMap: texture_depth_2d;\n            var uFogShadowMapSampler: sampler_comparison;\n        #else\n            var uFogShadowMap: texture_2d<f32>;\n            var uFogShadowMapSampler: sampler;\n        #endif\n\n        fn sampleFogShadow(worldPos: vec3f, viewDepth: f32) -> f32 {\n\n            // no shadow past the shadow distance\n            if (viewDepth >= uniform.uFogShadowParams.w) {\n                return 1.0;\n            }\n\n            // cascade index based on the view depth\n            let comparisons: vec4f = step(uniform.uFogShadowCascadeDistances, vec4f(viewDepth));\n            let cascadeIndex: i32 = i32(min(dot(comparisons, vec4f(1.0)), uniform.uFogShadowParams.x - 1.0));\n\n            let shadowCoord: vec3f = (uniform.uFogShadowMatrixPalette[cascadeIndex] * vec4f(worldPos, 1.0)).xyz;\n            let z: f32 = shadowCoord.z - uniform.uFogShadowParams.y;\n\n            #ifdef FOG_SHADOW_PCF\n                // hardware comparison on the depth format shadow map\n                return textureSampleCompareLevel(uFogShadowMap, uFogShadowMapSampler, shadowCoord.xy, z);\n            #else\n                // manual comparison on the color format shadow map storing depth (PCSS / VSM)\n                return step(z, textureSampleLevel(uFogShadowMap, uFogShadowMapSampler, shadowCoord.xy, 0.0).r);\n            #endif\n        }\n    #endif\n\n    // interleaved gradient noise\n    fn fogNoise(fragCoord: vec2f) -> f32 {\n        const magic: vec3f = vec3f(0.06711056, 0.00583715, 52.9829189);\n        return fract(magic.z * fract(dot(fragCoord, magic.xy)));\n    }\n\n    // normalized Henyey-Greenstein phase function\n    fn fogPhase(cosTheta: f32, g: f32) -> f32 {\n        let g2: f32 = g * g;\n        let denom: f32 = 1.0 + g2 - 2.0 * g * cosTheta;\n        return (1.0 - g2) / (12.56637 * denom * sqrt(denom));\n    }\n\n    @fragment\n    fn fragmentMain(input: FragmentInput) -> FragmentOutput {\n        var output: FragmentOutput;\n\n        // world space ray for this pixel (perspective projection). Note that uv0 addresses\n        // textures (getImageEffectUV flips it on WebGPU), so undo the flip to get NDC\n        let ndcUV: vec2f = vec2f(input.uv0.x, 1.0 - input.uv0.y);\n        let ndc: vec2f = ndcUV * 2.0 - 1.0;\n        let rayDir: vec3f = normalize((uniform.uFogInvView * vec4f(ndc * uniform.uFogProjScale, -1.0, 0.0)).xyz);\n\n        // distance along the ray to the scene surface\n        let rayDot: f32 = max(dot(rayDir, uniform.uFogCameraFwd), 0.001);\n        let rayLength: f32 = min(getLinearScreenDepth(input.uv0) / rayDot, uniform.uFogParams.w);\n\n        let stepCount: f32 = uniform.uFogScatterParams.y;\n        let dt: f32 = rayLength / stepCount;\n\n        // per-pixel noise offsets the samples along the ray to hide banding, and cycles over\n        // frames when TAA is used to temporally accumulate to a smooth result\n        let noise: f32 = fract(fogNoise(pcPosition.xy) + uniform.uFogScatterParams.z);\n\n        // single phase function evaluation, as the light direction is constant along the ray\n        let sunLight: vec3f = uniform.uFogLightColor * fogPhase(dot(rayDir, uniform.uFogLightDir), uniform.uFogScatterParams.x);\n\n        var inscatter: vec3f = vec3f(0.0);\n        var transmittance: f32 = 1.0;\n\n        for (var i: f32 = 0.0; i < stepCount; i += 1.0) {\n            let t: f32 = (i + noise) * dt;\n            let pos: vec3f = uniform.uFogCameraPos + rayDir * t;\n\n            // exponential height fog density, constant below the base height\n            let density: f32 = uniform.uFogParams.x * exp(-uniform.uFogParams.z * max(pos.y - uniform.uFogParams.y, 0.0));\n\n            var shadow: f32 = 1.0;\n            #ifdef FOG_SHADOWS\n                shadow = mix(1.0, sampleFogShadow(pos, t * rayDot), uniform.uFogScatterParams.w);\n            #endif\n\n            // accumulate in-scattered light and update transmittance (Beer-Lambert)\n            let radiance: vec3f = sunLight * shadow + uniform.uFogAmbient;\n            inscatter += transmittance * uniform.uFogTint * radiance * (density * dt);\n            transmittance *= exp(-density * dt);\n\n            if (transmittance < 0.005) {\n                break;\n            }\n        }\n\n        output.color = vec4f(inscatter, transmittance);\n        return output;\n    }\n";
export default _default;
