/* COPYRIGHT Esri - https://js.arcgis.com/5.1.2/LICENSE.txt */
import{ComponentData as e}from"../views/3d/webgl-engine/collections/Component/Material/ComponentData.glsl.js";import{ForwardLinearDepthToWriteShadowMap as o}from"../views/3d/webgl-engine/core/shaderLibrary/ForwardLinearDepthToWriteShadowMap.glsl.js";import{isColor as a,isShadow as r}from"../views/3d/webgl-engine/core/shaderLibrary/ShaderOutput.js";import{SlicePass as l}from"../views/3d/webgl-engine/core/shaderLibrary/Slice.glsl.js";import{TextureCoordinateAttribute as i}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/TextureCoordinateAttribute.glsl.js";import{VertexColor as t}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/VertexColor.glsl.js";import{VertexNormal as n}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/VertexNormal.glsl.js";import{VertexPosition as s}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/VertexPosition.glsl.js";import{OutputDepth as d}from"../views/3d/webgl-engine/core/shaderLibrary/output/OutputDepth.glsl.js";import{OutputHighlight as g}from"../views/3d/webgl-engine/core/shaderLibrary/output/OutputHighlight.glsl.js";import{OutputHighlightOverlay as c}from"../views/3d/webgl-engine/core/shaderLibrary/output/OutputHighlightOverlay.js";import{ReadDepth as m}from"../views/3d/webgl-engine/core/shaderLibrary/output/ReadDepth.glsl.js";import{computeFragmentNormals as v}from"../views/3d/webgl-engine/core/shaderLibrary/shading/ComputeFragmentNormals.glsl.js";import{ComputeMaterialColor as u}from"../views/3d/webgl-engine/core/shaderLibrary/shading/ComputeMaterialColor.glsl.js";import{ComputeNormalTextureDraw as h}from"../views/3d/webgl-engine/core/shaderLibrary/shading/ComputeNormalTexture.glsl.js";import{EvaluateSceneLighting as w,addLightingGlobalFactor as p}from"../views/3d/webgl-engine/core/shaderLibrary/shading/EvaluateSceneLighting.glsl.js";import{addMainLightIntensity as b,addMainLightDirection as f}from"../views/3d/webgl-engine/core/shaderLibrary/shading/MainLighting.glsl.js";import{PhysicallyBasedRenderingParameters as y}from"../views/3d/webgl-engine/core/shaderLibrary/shading/PhysicallyBasedRenderingParameters.glsl.js";import{PiUtils as C}from"../views/3d/webgl-engine/core/shaderLibrary/shading/PiUtils.glsl.js";import{ReadBaseColorTexture as x}from"../views/3d/webgl-engine/core/shaderLibrary/shading/ReadBaseColorTexture.glsl.js";import{ReadShadowMapPassFragment as L}from"../views/3d/webgl-engine/core/shaderLibrary/shading/ReadShadowMap.glsl.js";import{OverlayIM as S}from"../views/3d/webgl-engine/core/shaderLibrary/terrain/Overlay.glsl.js";import{DiscardOrAdjustAlphaDraw as O}from"../views/3d/webgl-engine/core/shaderLibrary/util/DiscardOrAdjustAlpha.glsl.js";import{BooleanDrawUniform as j}from"../views/3d/webgl-engine/core/shaderModules/BooleanDrawUniform.js";import{If as N,glsl as $}from"../views/3d/webgl-engine/core/shaderModules/glsl.js";import{Texture2DBindUniform as R}from"../views/3d/webgl-engine/core/shaderModules/Texture2DBindUniform.js";import{SnowCover as T}from"../views/3d/webgl-engine/effects/snowcover/SnowCover.glsl.js";import{alphaCutoff as M}from"../views/3d/webgl-engine/shaders/alphaCutoff.glsl.js";import{outputColorHighlightOLID as D}from"../views/3d/webgl-engine/shaders/OutputColorHighlightOLID.glsl.js";import{getPlanetRadius as W,sphereDepthInterpolate as P}from"../views/3d/webgl-engine/shaders/SphereDepthInterpolate.glsl.js";import{ShaderBuilder as A}from"../views/webgl/ShaderBuilder.js";function U(U){const F=new A,{vertex:V,fragment:z}=F;F.include(s,U),F.include(n,U),F.include(t,U),F.include(i,U),F.include(e,U),F.include(O,U),z.include(l,U),F.include(x,U);const{output:B,pbrMode:E,hasNormalTexture:I,snowCover:G,receiveShadows:_,shadeNormals:H,spherical:k,sphericalSR:q,overlayEnabled:J,componentDataType:K,vertexDiscardMode:Q,renderOccluded:X,isGroundSlice:Y}=U,Z=1===E||2===E;Z&&(F.include(y,U),I&&F.include(h,U));const ee=r(B),oe=11===B,ae=ee&&1===K,re=W(U);J&&(z.include(w,U),F.include(S,U),V.include(C),V.uniforms.add(new j("useENUForGlobalOverlayUV",e=>e.useENUForGlobalOverlayUV)),z.uniforms.add(new j("useENUForGlobalOverlayUV",e=>e.useENUForGlobalOverlayUV)),V.constants.add("invRadius","float",1/re).code.add(`vec2 projectOverlay(vec3 pos) { return pos.xy ${N(k,"/ (1.0 + invRadius * pos.z)")}; }`));const le=J&&a(B)&&4===E;le&&(F.varyings.add("tbnTangent","vec3"),F.varyings.add("tbnBiTangent","vec3"),F.varyings.add("groundNormal","vec3"));const ie=0===Q,te=2===Q;if(F.include(L,U),F.include(o,U),V.include(M),V.main.add($`
    bool castShadows;
    vec4 externalColor = forwardExternalColor(castShadows);
    ${N(ae,"if(!castShadows) { gl_Position = vec4(vec3(1e38), 1.0); return; }")}
    ${N(!ie,`if (externalColor.a ${te?">":"<="} opacityCutoff) {\n         gl_Position = vec4(vec3(1e38), 1.0); return;\n       }`)}
    ${N(oe,"externalColor.a = 1.0;")}

    forwardPosition(readElevationOffset());
    forwardNormal();
    forwardTextureCoordinates();
    forwardVertexColor();
    forwardLinearDepthToReadShadowMap();
    forwardLinearDepthToWriteShadowMap();
    forwardEmissiveStrength();
    forwardObjectAndLayerIdColor();
    ${N(le,k?$`
            groundNormal = normalize(positionWorld());
            tbnTangent = normalize(cross(vec3(0.0, 0.0, 1.0), groundNormal));
            tbnBiTangent = normalize(cross(groundNormal, tbnTangent));`:$`
            groundNormal = vec3(0.0, 0.0, 1.0);
            tbnTangent = vec3(1.0, 0.0, 0.0);
            tbnBiTangent = vec3(0.0, 1.0, 0.0);`)}
    ${N(J,N(k,"\n        if (useENUForGlobalOverlayUV) {\n          setOverlayVTC(projectOverlay(positionForDraping()));\n        } else {\n          vtcOverlay = vec4(0.0); // Definite assignment\n        }\n      ","setOverlayVTC(projectOverlay(positionForDraping()));"))}

    if (externalColor.a < alphaCutoff) {
      // Discard this vertex
      gl_Position = vec4(1e38, 1e38, 1e38, 1.0);
      return;
    }
  `),a(B))return F.include(u,U),F.include(v,U),F.include(D,U),z.include(w,U),z.include(T,U),z.include(M),z.constants.add("pRadius","float",re).code.add($`
      float evaluateShadow() {
        return ${_?"readShadowMap(vPositionWorldCameraRelative, linearDepth)":"0.0"};
      }
    `).main.add($`
      ${N(!Y,"discardBySlice(vPositionWorldCameraRelative);")}

      vec4 textureColor = readBaseColorTexture();
      discardOrAdjustAlpha(textureColor);

      // When rendering the occluded overlay, we still need to read the base color texture because we need to use the
      // same discard logic. However after that to render only the draped overlay, we simply set the base texture color
      // to zero.
      ${N(X,$`textureColor = vec4(0);`)}

      ${N(J,$`
        ${N(k,$`
            vec4 overlayUVs;
            if (useENUForGlobalOverlayUV) {
              overlayUVs = vtcOverlay;
            } else {
              const float rad2deg1 = 180.0 / PI;

              vec3 wPos = positionWorld();

              float oRadius = length(wPos.xyz);
              float oLonRad = atan(wPos.y, wPos.x);
              float sinLat = wPos.z / oRadius;

              ${N(1===q,$`
                  const float halfSemiMajorAxis = 0.5 * pRadius;
                  vec2 posWM = vec2(
                    oLonRad * pRadius,
                    halfSemiMajorAxis * log((1.0 + sinLat) / (1.0 - sinLat))
                  );

                  vec2 overlayUV = posWM;
              `,$`
                float oLatRad = asin(clamp(sinLat,-1.0,1.0));
                vec2 posWgs84 = vec2(rad2deg1 * oLonRad, rad2deg1 * oLatRad);
                vec2 overlayUV = posWgs84;
              `)}
              overlayUVs = vec4(overlayUV, overlayUV) * overlayTexScale + overlayTexOffset;
            }
          `,$`vec4 overlayUVs = vtcOverlay;`)}

        vec4 overlayColor = getOverlayColor(ovColorTex, overlayUVs);

        /* Early discard to only emit when we have overlay */
        ${N(X,$`if (overlayColor.a < alphaCutoff) { discard; }`)}
        `)}

      vec4 externalColor;
      int externalColorMixMode;
      readExternalColor(externalColor, externalColorMixMode);

      vec4 materialColor = computeMaterialColor(textureColor, externalColor, externalColorMixMode);
    `),Z?(b(z),k&&p(z),z.main.add($`
        applyPBRFactors();
        ${N(1===E,$`if (externalColorMixMode == 3) {
              mrr = vec3(0.0, 0.6, 0.2);
            }`)}
        float additionalIrradiance = 0.02 * mainLightIntensity[2];
        ${N(I,"mat3 tangentSpace = computeTangentSpace(fragmentFaceNormal, vPositionWorldCameraRelative, vuv0);")}
        vec3 shadingNormal = ${I?"computeTextureNormal(tangentSpace, vuv0)":"fragmentShadingNormal"};
        vec3 groundNormal = ${k?$`normalize(positionWorld())`:$`vec3(0.0, 0.0, 1.0)`};

        vec3 viewDir = normalize(vPositionWorldCameraRelative);
        float ssao = 1.0 - occlusion * evaluateAmbientOcclusionInverse();
        ${N(G,$`float snow = getSnow(fragmentFaceNormal, normalize(positionWorld()));
                 materialColor.rgb = mix(materialColor.rgb, vec3(1.1), snow);
                 ssao = mix(ssao, 0.5 * ssao, snow);
                 shadingNormal = mix(shadingNormal, fragmentFaceNormal, snow);`)}
        ${N(J,"materialColor = materialColor * (1.0 - overlayColor.a) + overlayColor;")}

        vec3 additionalLight = evaluateAdditionalLighting(ssao, positionWorld());
        ${N(k,"float additionalAmbientScale = additionalDirectedAmbientLight(positionWorld());")}
        ${k?$`float shadow = max(lightingGlobalFactor * (1.0 - additionalAmbientScale), evaluateShadow());`:"float shadow = evaluateShadow();"}
        vec4 shadedColor = vec4(evaluateSceneLightingPBR(shadingNormal, materialColor.rgb, shadow, ssao, additionalLight, viewDir, groundNormal, mrr, additionalIrradiance), materialColor.a);
        `)):(f(z),k&&p(z),le&&z.uniforms.add(new R("ovNormalTex",e=>e.overlay?.getTexture(3))),z.main.add($`
        ${N(k,"float additionalAmbientScale = additionalDirectedAmbientLight(positionWorld());")}
        float shadow = ${_?k?"max(lightingGlobalFactor * (1.0 - additionalAmbientScale), evaluateShadow())":"evaluateShadow()":k?"lightingGlobalFactor * (1.0 - additionalAmbientScale)":"0.0"};

        ${N(_&&1!==H,$`
            float dotFL = dot(fragmentFaceNormal, mainLightDirection);
            if( dotFL <= 0.0) shadow = 1.0;
        `)}
        ${N(G,$`float snow = getSnow(fragmentFaceNormal, normalize(positionWorld()));
               materialColor.rgb = mix(materialColor.rgb, vec3(1), snow);`)}

        // At global scale we create some additional ambient light based on the main light to simulate global illumination
        float ssao = evaluateAmbientOcclusion();
        vec3 additionalLight = evaluateAdditionalLighting(ssao, positionWorld());

        ${N(J,"materialColor = materialColor * (1.0 - overlayColor.a) + overlayColor;")}

        vec4 shadedColor = vec4(evaluateSceneLighting(fragmentShadingNormal, materialColor.rgb, shadow, ssao, additionalLight), materialColor.a);
        ${N(le,$`vec4 overlayWaterMask = getOverlayColor(ovNormalTex, overlayUVs);
                 float waterNormalLength = length(overlayWaterMask);
                 if (waterNormalLength > 0.95) {
                   mat3 tbnMatrix = mat3(tbnTangent, tbnBiTangent, groundNormal);
                   vec4 waterColorLinear = getOverlayWaterColor(overlayWaterMask, overlayColor, -normalize(vPositionWorldCameraRelative), shadow, groundNormal, tbnMatrix, vPosition_view, positionWorld());
                   vec4 waterColorNonLinear = delinearizeGamma(vec4(waterColorLinear.xyz, 1.0));
                   // un-gamma the ground color to mix in linear space
                   shadedColor = mix(shadedColor, waterColorNonLinear, waterColorLinear.w);
                 }`)}
      `)),z.main.add(`\n      ${N(Y,"if(rejectBySlice(vPositionWorldCameraRelative)) shadedColor.a *= groundSliceOpacity;")}\n\n      outputColorHighlightOLID(applySlice(shadedColor, vPositionWorldCameraRelative), materialColor.rgb ${N(G,", snow")});\n    `),U.sphereDepthInterpolate&&(F.include(P,U),F.fragment.include(m),z.main.add($`vec3 worldRay = normalize(vPositionWorldCameraRelative);
vec3 viewRay = normalize(vPosition_view);
gl_FragDepth = delinearizeDepth(sphereDepthInterpolate(worldRay, viewRay, linearizeDepth(gl_FragCoord.z)));`)),F;const ne=4===B,se=10===B,de=ee||8===B||9===B;return de&&F.include(d,U),ne&&F.include(v,U),J&&F.include(c,U),F.include(g,U),z.main.add($`
    ${N(!Y,"discardBySlice(vPositionWorldCameraRelative);")}

    vec4 textureColor = readBaseColorTexture();
    discardOrAdjustAlpha(textureColor);

    ${N(de,"outputDepth(linearDepth);")}
    ${N(ne,$`fragColor = vec4(vec3(0.5) + 0.5 * fragmentFaceNormalView, 1.0);`)}
    ${N(oe,J?"fragColor = getOverlayColorTexel();":"outputObjectAndLayerIdColor();")}
    ${N(se,N(J,$`calculateOcclusionAndOutputHighlight(getAllOverlayHighlightValuesEncoded());`,$`calculateOcclusionAndOutputHighlight();`))}`),F}const F=Object.freeze(Object.defineProperty({__proto__:null,build:U},Symbol.toStringTag,{value:"Module"}));export{F as C,U as b};
