declare const _default: "\n\nfn fractSinRand(uv: vec2f) -> f32 {\n    let PI: f32 = 3.141592653589793;\n    let a: f32 = 12.9898; let b: f32 = 78.233; let c: f32 = 43758.5453;\n    let dt: f32 = dot(uv.xy, vec2f(a, b));\n    let sn: f32 = dt % PI;\n    return fract(sin(sn) * c);\n}\n\n// struct to hold precomputed constants and current state\nstruct VogelDiskData {\n    invNumSamples: f32,\n    initialAngle: f32,\n    currentPointId: f32,\n}\n\n// prepare the Vogel disk constants and initialize the current state in the struct\nfn prepareDiskConstants(data: ptr<function, VogelDiskData>, sampleCount: i32, randomSeed: f32) {\n    let pi2: f32 = 6.28318530718;\n    data.invNumSamples = 1.0 / f32(sampleCount);\n    data.initialAngle = randomSeed * pi2;\n    data.currentPointId = 0.0;\n}\n\n\nfn generateDiskSample(data: ptr<function, VogelDiskData>) -> vec2f {\n    let GOLDEN_ANGLE: f32 = 2.399963;\n    let r: f32 = sqrt((data.currentPointId + 0.5) * data.invNumSamples);\n    let theta: f32 = data.currentPointId * GOLDEN_ANGLE + data.initialAngle;\n\n    let offset: vec2f = vec2f(cos(theta), sin(theta)) * pow(r, 1.33);\n\n    data.currentPointId = data.currentPointId + 1.0;\n    return offset;\n}\n\nfn PCSSFindBlocker(shadowMap: texture_2d<f32>, shadowMapSampler: sampler, avgBlockerDepth: ptr<function, f32>, numBlockers: ptr<function, i32>,\n    shadowCoords: vec2f, z: f32, shadowBlockerSamples: i32, searchWidthUv: f32, randomSeed: f32) {\n\n    var diskData: VogelDiskData;\n    prepareDiskConstants(&diskData, shadowBlockerSamples, randomSeed);\n\n    var blockerSum: f32 = 0.0;\n    var numBlockers_local: i32 = 0;\n\n    for( var i: i32 = 0; i < shadowBlockerSamples; i = i + 1 ) {\n        let diskUV: vec2f = generateDiskSample(&diskData);\n        let sampleUV: vec2f = shadowCoords + diskUV * searchWidthUv;\n        let shadowMapDepth: f32 = textureSampleLevel(shadowMap, shadowMapSampler, sampleUV, 0.0).r;\n        if ( shadowMapDepth < z ) {\n            blockerSum = blockerSum + shadowMapDepth;\n            numBlockers_local = numBlockers_local + 1;\n        }\n    }\n    *avgBlockerDepth = blockerSum / f32(numBlockers_local);\n    *numBlockers = numBlockers_local;\n}\n\nfn PCSSFilter(shadowMap: texture_2d<f32>, shadowMapSampler: sampler, uv: vec2f, receiverDepth: f32, shadowSamples: i32, filterRadius: f32, randomSeed: f32) -> f32 {\n\n    var diskData: VogelDiskData;\n    prepareDiskConstants(&diskData, shadowSamples, randomSeed);\n\n    var sum: f32 = 0.0;\n    for (var i: i32 = 0; i < shadowSamples; i = i + 1) {\n        let offsetUV: vec2f = generateDiskSample(&diskData) * filterRadius;\n        let depth: f32 = textureSampleLevel(shadowMap, shadowMapSampler, uv + offsetUV, 0.0).r;\n        sum = sum + step(receiverDepth, depth);\n    }\n    return sum / f32(shadowSamples);\n}\n\nfn PCSSDirectional(shadowMap: texture_2d<f32>, shadowMapSampler: sampler, shadowCoords: vec3f, cameraParams: vec4f, softShadowParams: vec4f) -> f32 {\n\n    let receiverDepth: f32 = shadowCoords.z;\n    // for sampling against the shadow map we clamp so cleared cells (depth = 1) don't get\n    // treated as blockers when the receiver sits outside the tightened cascade range.\n    // worldDist further down uses the *unclamped* receiverDepth so it stays cascade-stable.\n    let receiverDepthClamped: f32 = min(receiverDepth, 0.9999);\n    let randomSeed: f32 = fractSinRand(pcPosition.xy);\n    let shadowSamples: i32 = i32(softShadowParams.x);\n    let shadowBlockerSamples: i32 = i32(softShadowParams.y);\n    let penumbraSize: f32 = softShadowParams.z;       // world-space \"area size of the light\"\n    let penumbraFalloff: f32 = softShadowParams.w;    // curve shape (>= 1)\n\n    // World-space PCSS. cameraParams.x is the ortho radius (world half-extent) of the\n    // directional shadow camera; cameraParams.y/z are far/near. Working in world units\n    // makes softness invariant to how the shadow camera tightens its depth bounds per\n    // light direction.\n    let orthoRadius: f32 = cameraParams.x;\n    let depthRange: f32 = cameraParams.y - cameraParams.z;\n    let worldPerUv: f32 = 2.0 * orthoRadius;\n\n    var filterRadius: f32;\n\n    // contact hardening path\n    if (shadowBlockerSamples > 0) {\n\n        // search width bounds the largest possible penumbra (blocker at far end of depth range)\n        let searchWidthUv: f32 = (penumbraSize * depthRange) / worldPerUv;\n\n        var avgBlockerDepth: f32 = 0.0;\n        var numBlockers: i32 = 0;\n        PCSSFindBlocker(shadowMap, shadowMapSampler, &avgBlockerDepth, &numBlockers, shadowCoords.xy, receiverDepthClamped, shadowBlockerSamples, searchWidthUv, randomSeed);\n\n        // early out when no blockers are present\n        if (numBlockers < 1) {\n            return 1.0;\n        }\n\n        // World-space PCSS with shape control. The saturating curve reaches penumbraSize*depthRange\n        // when the blocker sits at the far end of the caster depth range; higher penumbraFalloff\n        // makes the softening climb faster (so the same blocker distance produces a wider penumbra).\n        // falloff=1 is the linear baseline.\n        let worldDist: f32 = max((receiverDepth - avgBlockerDepth) * depthRange, 0.0);\n        let t: f32 = clamp(worldDist / depthRange, 0.0, 1.0);\n        let shape: f32 = 1.0 - pow(1.0 - t, penumbraFalloff);\n        let penumbraWorld: f32 = shape * penumbraSize * depthRange;\n        filterRadius = penumbraWorld / worldPerUv;\n\n    } else {\n\n        // constant filter size, no contact hardening \u2014 penumbraSize is the world-space radius\n        filterRadius = penumbraSize / worldPerUv;\n    }\n\n    // filtering\n    return PCSSFilter(shadowMap, shadowMapSampler, shadowCoords.xy, receiverDepthClamped, shadowSamples, filterRadius, randomSeed);\n}\n\nfn getShadowPCSS(shadowMap: texture_2d<f32>, shadowMapSampler: sampler, shadowCoord: vec3f, shadowParams: vec4f, cameraParams: vec4f, softShadowParams: vec4f, lightDir: vec3f) -> f32 { // lightDir unused? Kept param.\n    return PCSSDirectional(shadowMap, shadowMapSampler, shadowCoord, cameraParams, softShadowParams);\n}\n";
export default _default;
