/* COPYRIGHT Esri - https://js.arcgis.com/5.0/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 r,isShadow as a}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{ReadShadowMapPass as L}from"../views/3d/webgl-engine/core/shaderLibrary/shading/ReadShadowMap.glsl.js";import{terrainDepthTest as S}from"../views/3d/webgl-engine/core/shaderLibrary/shading/TerrainDepthTest.glsl.js";import{OverlayIM as O}from"../views/3d/webgl-engine/core/shaderLibrary/terrain/Overlay.glsl.js";import{DiscardOrAdjustAlphaDraw as j}from"../views/3d/webgl-engine/core/shaderLibrary/util/DiscardOrAdjustAlpha.glsl.js";import{BooleanDrawUniform as N}from"../views/3d/webgl-engine/core/shaderModules/BooleanDrawUniform.js";import{If as $,glsl as T}from"../views/3d/webgl-engine/core/shaderModules/glsl.js";import{Texture2DBindUniform as D}from"../views/3d/webgl-engine/core/shaderModules/Texture2DBindUniform.js";import{SnowCover as R}from"../views/3d/webgl-engine/effects/weather/SnowCover.glsl.js";import{outputColorHighlightOLID as M}from"../views/3d/webgl-engine/shaders/OutputColorHighlightOLID.glsl.js";import{getPlanetRadius as P,sphereDepthInterpolate as W}from"../views/3d/webgl-engine/shaders/SphereDepthInterpolate.glsl.js";import{ShaderBuilder as A}from"../views/webgl/ShaderBuilder.js";import{alphaCutoff as F}from"../webscene/support/AlphaCutoff.js";function U(U){const V=new A,{vertex:z,fragment:B}=V;V.include(s,U),V.include(n,U),V.include(t,U),V.include(i,U),V.include(e,U),V.include(j,U),B.include(l,U),V.include(x,U),V.include(S,U);const{output:E,pbrMode:_,hasNormalTexture:I,snowCover:G,receiveShadows:H,shadeNormals:k,spherical:q,sphericalSR:J,overlayEnabled:K,componentDataType:Q,vertexDiscardMode:X,renderOccluded:Y,isGroundSlice:Z}=U,ee=1===_||2===_;ee&&(V.include(y,U),I&&V.include(h,U));const oe=a(E),re=oe&&1===Q,ae=P(U);K&&(B.include(w,U),V.include(O,U),z.include(C),z.uniforms.add(new N("useENUForGlobalOverlayUV",e=>e.useENUForGlobalOverlayUV)),B.uniforms.add(new N("useENUForGlobalOverlayUV",e=>e.useENUForGlobalOverlayUV)),z.constants.add("invRadius","float",1/ae).code.add(`vec2 projectOverlay(vec3 pos) { return pos.xy ${$(q,"/ (1.0 + invRadius * pos.z)")}; }`));const le=K&&r(E)&&4===_;le&&(V.varyings.add("tbnTangent","vec3"),V.varyings.add("tbnBiTangent","vec3"),V.varyings.add("groundNormal","vec3"));const ie=0===X,te=2===X,ne=1-1/255;if(V.include(L,U),V.include(o,U),z.main.add(T`
    bool castShadows;
    vec4 externalColor = forwardExternalColor(castShadows);
    ${$(re,"if(!castShadows) { gl_Position = vec4(vec3(1e38), 1.0); return; }")}
    ${$(!ie,`{ if (externalColor.a ${te?">":"<="} ${T.float(ne)}) { gl_Position = vec4(vec3(1e38), 1.0); return; } }`)}
    ${$(9===E,"externalColor.a = 1.0;")}

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

    if (externalColor.a < ${T.float(F)}) {
      // Discard this vertex
      gl_Position = vec4(1e38, 1e38, 1e38, 1.0);
      return;
    }
  `),r(E))return V.include(u,U),V.include(v,U),B.include(w,U),V.include(M,U),B.include(R,U),B.constants.add("pRadius","float",ae).code.add(T`
      float evaluateShadow() {
        return ${H?"readShadowMap(vPositionWorldCameraRelative, linearDepth)":"0.0"};
      }
    `).main.add(T`
      ${$(!Z,"discardBySlice(vPositionWorldCameraRelative);")}
      discardByTerrainDepth();

      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.
      ${$(Y,T`textureColor = vec4(0);`)}

      ${$(K,T`
        ${$(q,T`
            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;

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

                  vec2 overlayUV = posWM;
              `,T`
                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;
            }
          `,T`vec4 overlayUVs = vtcOverlay;`)}

        vec4 overlayColor = getOverlayColor(ovColorTex, overlayUVs);

        /* Early discard to only emit when we have overlay */
        ${$(Y,T`if (overlayColor.a < ${T.float(F)}) { discard; }`)}
        `)}

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

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

        vec3 viewDir = normalize(vPositionWorldCameraRelative);
        float ssao = 1.0 - occlusion * evaluateAmbientOcclusionInverse();
        ${$(G,T`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);`)}
        ${$(K,"materialColor = materialColor * (1.0 - overlayColor.a) + overlayColor;")}

        vec3 additionalLight = evaluateAdditionalLighting(ssao, positionWorld());
        ${$(q,"float additionalAmbientScale = additionalDirectedAmbientLight(positionWorld());")}
        ${q?T`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(B),q&&p(B),le&&B.uniforms.add(new D("ovNormalTex",e=>e.overlay?.getTexture(3))),B.main.add(T`
        ${$(q,"float additionalAmbientScale = additionalDirectedAmbientLight(positionWorld());")}
        float shadow = ${H?q?"max(lightingGlobalFactor * (1.0 - additionalAmbientScale), evaluateShadow())":"evaluateShadow()":q?"lightingGlobalFactor * (1.0 - additionalAmbientScale)":"0.0"};

        ${$(H&&!k,T`
            float dotFL = dot(fragmentFaceNormal, mainLightDirection);
            if( dotFL <= 0.0) shadow = 1.0;
        `)}
        ${$(G,T`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());

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

        vec4 shadedColor = vec4(evaluateSceneLighting(fragmentShadingNormal, materialColor.rgb, shadow, ssao, additionalLight), materialColor.a);
        ${$(le,T`vec4 overlayWaterMask = getOverlayColor(ovNormalTex, vtcOverlay);
                 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);
                 }`)}
      `)),B.main.add(`\n      ${$(Z,"if(rejectBySlice(vPositionWorldCameraRelative)) shadedColor.a *= groundSliceOpacity;")}\n\n      outputColorHighlightOLID(applySlice(shadedColor, vPositionWorldCameraRelative), materialColor.rgb ${$(G,", snow")});\n    `),U.sphereDepthInterpolate&&(V.include(W,U),V.fragment.include(m),B.main.add(T`if (sphereFade()>0.0) {
vec3 worldRay = normalize(vPositionWorldCameraRelative);
vec3 viewRay = normalize(vPosition_view);
gl_FragDepth = delinearizeDepth(sphereDepthInterpolate(worldRay, viewRay, linearizeDepth(gl_FragCoord.z)));
} else {
gl_FragDepth = gl_FragCoord.z;
}`)),V;const se=2===E,de=9===E,ge=8===E,ce=oe||6===E||7===E;return ce&&V.include(d,U),se&&V.include(v,U),K&&V.include(c,U),V.include(g,U),B.main.add(T`
    ${$(!Z,"discardBySlice(vPositionWorldCameraRelative);")}

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

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