/* COPYRIGHT Esri - https://js.arcgis.com/5.1.2/LICENSE.txt */
import{create as e}from"../core/libs/gl-matrix-2/factories/vec2f64.js";import{clone as o,fromValues as r,create as a}from"../core/libs/gl-matrix-2/factories/vec4f64.js";import{ScreenSpacePass as t}from"../views/3d/webgl-engine/core/shaderLibrary/ScreenSpacePass.glsl.js";import{BlendColorsPremultiplied as s,premultiplyAlpha as l}from"../views/3d/webgl-engine/core/shaderLibrary/util/BlendColorsPremultiplied.glsl.js";import{CameraSpace as n}from"../views/3d/webgl-engine/core/shaderLibrary/util/CameraSpace.glsl.js";import{Float2PassUniform as i}from"../views/3d/webgl-engine/core/shaderModules/Float2PassUniform.js";import{Float4PassUniform as d}from"../views/3d/webgl-engine/core/shaderModules/Float4PassUniform.js";import{Float4sPassUniform as m}from"../views/3d/webgl-engine/core/shaderModules/Float4sPassUniform.js";import{FloatPassUniform as h}from"../views/3d/webgl-engine/core/shaderModules/FloatPassUniform.js";import{FloatsPassUniform as p}from"../views/3d/webgl-engine/core/shaderModules/FloatsPassUniform.js";import{glsl as u,If as c}from"../views/3d/webgl-engine/core/shaderModules/glsl.js";import{IntegerPassUniform as g}from"../views/3d/webgl-engine/core/shaderModules/IntegerPassUniform.js";import{Texture2DPassUniform as v}from"../views/3d/webgl-engine/core/shaderModules/Texture2DPassUniform.js";import{maxColorRampSize as w}from"../views/3d/webgl-engine/shaders/colorRampParameters.js";import{S as C}from"./ShadowCastAccumulate.glsl.js";import{NoParameters as f}from"../views/webgl/NoParameters.js";import{ShaderBuilder as b}from"../views/webgl/ShaderBuilder.js";class S extends f{constructor(r){super(),this._data=r,this.sampleScale=e(),this.opacityFromElevation=1,this.gradientColorRamp=y,this.thresholdColor=o($),this.bandedGradientColorRamp=M,this.bandSize=.1,this.threshold=.5}get shadowCastMap(){return this._data.shadowCastTexture}}const R=.7,j=50/255,y=[[0,r(0,0,1,0)],[1,r(0,0,1,R)]],$=r(1,0,0,R),M=[[0,r(j,j,j,0)],[1,r(j,j,j,R)]];function z(e){const o=new b,r=o.fragment;o.include(n),o.include(t);const{rendersSunlight:a,visualization:f}=e;r.constants.add("inverseSampleValue","float",C),r.uniforms.add(new v("shadowCastMap",e=>e.shadowCastMap),new i("sampleScale",e=>e.sampleScale),new h("opacityFromElevation",e=>e.opacityFromElevation));const S=2===f,R=3===f,j=1===f;R&&r.include(s);const y=!S;switch(y&&r.code.add(u`vec4 evaluateColorRamp(float value) {
if (value <= vvColorValues[0]) {
return vvColorColors[0];
}
for (int i = 1; i < colorRampSize; ++i) {
if (vvColorValues[i] >= value) {
float f = (value - vvColorValues[i-1]) / (vvColorValues[i] - vvColorValues[i-1]);
return mix(vvColorColors[i-1], vvColorColors[i], f);
}
}
return vvColorColors[colorRampSize - 1];
}`),f){case 0:r.uniforms.add(new m("vvColorColors",w,e=>e.gradientColorRamp.flatMap(([e,o])=>l(P,o))),new g("colorRampSize",e=>e.gradientColorRamp.length),new p("vvColorValues",w,e=>e.gradientColorRamp.map(([e,o])=>e)));break;case 1:r.uniforms.add(new m("vvColorColors",w,e=>e.bandedGradientColorRamp.flatMap(([e,o])=>l(P,o))),new g("colorRampSize",e=>e.bandedGradientColorRamp.length),new p("vvColorValues",w,e=>e.bandedGradientColorRamp.map(([e,o])=>e)),new h("bandSize",e=>e.bandSize));break;case 3:r.uniforms.add(new d("uColor",e=>l(P,e.thresholdColor)),new h("threshold",e=>e.threshold),new m("vvColorColors",w,e=>e.gradientColorRamp.flatMap(([e,o])=>l(P,o))),new g("colorRampSize",e=>e.gradientColorRamp.length),new p("vvColorValues",w,e=>e.gradientColorRamp.map(([e,o])=>e)));break;case 2:r.uniforms.add(new d("uColor",e=>l(P,e.thresholdColor)),new h("threshold",e=>e.threshold))}const{type:$,selector:M,thresholdStrengthSelector:z}=R?{type:"vec2",selector:"rg",thresholdStrengthSelector:"strength.x"}:{type:"float",selector:"r",thresholdStrengthSelector:"strength"},V=!a;return r.main.add(u`
    ${$} numSamples = texture(shadowCastMap, uv).${M} * inverseSampleValue;

    fragColor = vec4(0.0);

    // In shadow space, zero accumulated samples can be skipped when they would render fully transparent.
    // In sunlight space, zero shadow samples may map to full-strength sunlight, so we keep them.
    ${c(V,u`
    if (${c(y,u`vvColorColors[0].a == 0.0 && `,"")}dot(numSamples, ${$}(1)) < 1.0) {
      return;
    }
    `)}

    // sampleScale is the number of total samples taken, so this brings strength to a 0-1 range.
    // note that sampleScale is always a vec2 even if we have only the primary channel.
    ${$} strength = numSamples * sampleScale.${M};

    ${c(a,u`strength = 1.0 - strength;`)}

    // in threshold mode, step the strength to 0 if we are at or below the threshold, 1 otherwise.
    ${c(S||R,u`
      float thresholdStrength = ${z};
      ${z} = 1.0 - step(thresholdStrength, threshold);
    `)}

    // bail out if we are below the threshold
    ${c(S,u`if (${z} == 0.0) { return; }`)}

    ${c(j,u`
      strength = ceil(strength / bandSize) * bandSize;
      `)}

    ${$} attenuation = opacityFromElevation * strength;

    ${c(R,u`
        vec4 thresholdColor = uColor * attenuation.r;
        vec4 gradientColor = evaluateColorRamp(attenuation.g);
        fragColor = blendColorsPremultiplied(${c(a,u`gradientColor, thresholdColor`,u`thresholdColor, gradientColor`)});
      `,c(S,u`
        fragColor = uColor * attenuation;
      `,u`
        fragColor = evaluateColorRamp(attenuation);
      `))}
  `),o}const P=a(),V=Object.freeze(Object.defineProperty({__proto__:null,ShadowCastVisualizePassParameters:S,build:z},Symbol.toStringTag,{value:"Module"}));export{S,V as a,z as b};
