/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.24/esri/copyright.txt for details.
*/
define(["exports","./_rollupPluginBabelHelpers","./mat4","./mat4f64","./vec3","./vec3f64","../views/3d/terrain/interfaces","../views/3d/webgl-engine/core/shaderLibrary/ShaderOutputOptions","../views/3d/webgl-engine/core/shaderLibrary/Slice.glsl","../views/3d/webgl-engine/core/shaderLibrary/Transform.glsl","../views/3d/webgl-engine/core/shaderLibrary/attributes/VertexTangent.glsl","../views/3d/webgl-engine/core/shaderLibrary/output/OutputDepth.glsl","../views/3d/webgl-engine/core/shaderLibrary/output/OutputHighlight.glsl","../views/3d/webgl-engine/core/shaderLibrary/shading/EvaluateAmbientOcclusion.glsl","../views/3d/webgl-engine/core/shaderLibrary/shading/EvaluateSceneLighting.glsl","../views/3d/webgl-engine/core/shaderLibrary/shading/NormalUtils.glsl","../views/3d/webgl-engine/core/shaderLibrary/shading/PhysicallyBasedRenderingParameters.glsl","../views/3d/webgl-engine/core/shaderLibrary/shading/ReadShadowMap.glsl","../views/3d/webgl-engine/core/shaderLibrary/terrain/Overlay.glsl","../views/3d/webgl-engine/core/shaderLibrary/terrain/TerrainTexture.glsl","../views/3d/webgl-engine/core/shaderLibrary/util/HeaderComment.glsl","../views/3d/webgl-engine/core/shaderModules/Float2PassUniform","../views/3d/webgl-engine/core/shaderModules/Float3DrawUniform","../views/3d/webgl-engine/core/shaderModules/Float3PassUniform","../views/3d/webgl-engine/core/shaderModules/FloatPassUniform","../views/3d/webgl-engine/core/shaderModules/interfaces","../views/3d/webgl-engine/core/shaderModules/Matrix4DrawUniform","../views/3d/webgl-engine/core/shaderModules/Matrix4PassUniform","../views/3d/webgl-engine/core/shaderModules/ShaderBuilder","../views/3d/webgl-engine/core/shaderModules/Texture2DPassUniform","../views/3d/webgl-engine/lib/VertexAttribute","../views/3d/webgl-engine/lighting/SceneLighting"],(function(e,r,a,i,o,l,n,t,s,d,g,v,c,m,u,w,h,p,b,y,f,C,x,S,M,P,F,O,T,D,L,_){"use strict";let z=function(e){function a(){return e.apply(this,arguments)||this}return r._inheritsLoose(a,e),a}(b.OverlayTerrainPassParameters);function U(e){const r=new T.ShaderBuilder;r.include(f.HeaderComment,{name:"Terrain Shader",output:e.output}),r.attributes.add(L.VertexAttribute.POSITION,"vec3"),r.attributes.add(L.VertexAttribute.UV0,"vec2"),r.attributes.add(L.VertexAttribute.NORMAL,"vec3");const{vertex:i,fragment:l}=r;if(i.uniforms.add([new O.Matrix4PassUniform("proj",((e,r)=>r.camera.projectionMatrix)),new F.Matrix4DrawUniform("view",((e,r)=>a.translate(N,r.camera.viewMatrix,e.origin))),new x.Float3DrawUniform("origin",(e=>e.origin))]),l.uniforms.add(new x.Float3DrawUniform("origin",(e=>e.origin))),e.output===t.ShaderOutput.Color){r.include(d.Transform),r.include(w.NormalUtils,e),r.include(y.TerrainTexture,e),r.include(u.EvaluateSceneLighting,e);const t=e.overlayMode!==b.OverlayMode.Disabled,v=e.overlayMode===b.OverlayMode.EnabledWithWater;t&&r.include(b.OverlayTerrain,{...e,pbrMode:h.PBRMode.Water}),v&&r.include(g.VertexTangent,e),r.varyings.add("vnormal","vec3"),r.varyings.add("vpos","vec3"),(e.atmosphere||e.screenSizePerspective)&&i.uniforms.add(new O.Matrix4PassUniform("viewNormal",((e,r)=>r.camera.viewInverseTransposeMatrix)));const c=e.receiveShadows&&!e.renderOccluded;c&&r.varyings.add("linearDepth","float"),e.tileBorders&&r.varyings.add("vuv","vec2"),e.atmosphere&&(i.uniforms.add(new S.Float3PassUniform("lightingMainDirection",((e,r)=>r.lighting.lightingMainDirection))),r.varyings.add("wnormal","vec3"),r.varyings.add("wlight","vec3")),e.screenSizePerspective&&(r.varyings.add("screenSizeDistanceToCamera","float"),r.varyings.add("screenSizeCosAngle","float")),i.code.add(P.glsl`
      void main(void) {
        vpos = position;
        vnormal = ${e.shading?P.glsl`normal`:P.glsl`getLocalUp(vpos, origin)`};
        vec2 uv = uv0;
        ${e.atmosphere?P.glsl`
        wnormal = normalize((viewNormal * vec4(normalize(vpos + origin), 1.0)).xyz);
        wlight = normalize((view  * vec4(lightingMainDirection, 1.0)).xyz);`:""}
        ${e.tileBorders?P.glsl`vuv = uv;`:""}
        ${e.screenSizePerspective?P.glsl`
        vec3 viewPos = (view * vec4(vpos, 1.0)).xyz;
        screenSizeDistanceToCamera = length(viewPos);
        vec3 viewSpaceNormal = (viewNormal * vec4(normalize(vpos + origin), 1.0)).xyz;
        screenSizeCosAngle = abs(viewSpaceNormal.z);`:""}
        gl_Position = transformPosition(proj, view, vpos);
        ${c?P.glsl`linearDepth = gl_Position.w;`:""}
        forwardTextureCoordinates(uv);
        ${t?P.glsl`setOverlayVTC(uv);`:""}
        ${v?P.glsl`forwardVertexTangent(vnormal);`:P.glsl``}
      }
    `),r.extensions.add("GL_OES_standard_derivatives"),r.extensions.add("GL_EXT_shader_texture_lod"),r.include(s.SliceDraw,e),r.include(u.EvaluateSceneLighting,e),r.include(m.EvaluateAmbientOcclusion,e),r.include(p.ReadShadowMapDraw,e),l.uniforms.add([new x.Float3DrawUniform("cameraPosition",((e,r)=>o.subtract($,r.camera.eye,e.origin))),new S.Float3PassUniform("viewDirection",((e,r)=>o.normalize($,o.set($,r.camera.viewMatrix[12],r.camera.viewMatrix[13],r.camera.viewMatrix[14])))),new M.FloatPassUniform("lightingGlobalFactor",((e,r)=>r.lighting.globalFactor)),new S.Float3PassUniform("lightingMainDirection",((e,r)=>r.lighting.lightingMainDirection)),new S.Float3PassUniform("lightingMainIntensity",((e,r)=>r.lighting.mainLight.intensity))]),l.constants.add("ambientBoostFactor","float",_.ambientBoost),v&&l.uniforms.add([new D.Texture2DPassUniform("ovWaterTex",((e,r)=>0===r.overlays.length?null:r.overlays[n.OverlayIndex.INNER].getNormalTexture(e.overlaySource))),new F.Matrix4DrawUniform("view",((e,r)=>a.translate(N,r.camera.viewMatrix,e.origin)))]),l.code.add(P.glsl`const float sliceOpacity = 0.2;
float lum(vec3 c) {
return (min(min(c.r, c.g), c.b) + max(max(c.r, c.g), c.b)) * 0.5;
}`),l.code.add(P.glsl`
      void main() {
        ${c?P.glsl`float shadow = readShadowMap(vpos, linearDepth);`:P.glsl`float shadow = 0.0;`}
        vec3 normal = normalize(vnormal);
        float vndl = dot(normal, lightingMainDirection);
        float ssao = evaluateAmbientOcclusionInverse();
        vec4 tileColor = getTileColor();
        ${t?P.glsl`
            vec4 overlayColorOpaque = getOverlayColor(ovColorTex, vtcOverlay);
            vec4 overlayColor = overlayOpacity * overlayColorOpaque;
            vec4 groundColor = tileColor;
            tileColor = tileColor * (1.0 - overlayColor.a) + overlayColor;`:""}
        if (rejectBySlice(vpos)) {
          tileColor *= sliceOpacity;
        }
        ${e.atmosphere?P.glsl`
            float ndotl = clamp(vndl, 0.0, 1.0);
            vec3 atm = vec3(clamp(1.0 - dot(-viewDirection, wnormal), 0.0, 1.0));
            atm *= clamp(1.0 - lum(tileColor.rgb) * 1.5, 0.0, 1.0); //avoid atmosphere on bright base maps
            atm *= clamp(ndotl * 2.0, 0.0, 1.0); // avoid atmosphere on dark side of the globe
            atm *= tileColor.a; // premultiply with tile alpha`:""}

        vec3 albedo = ${e.atmosphere?P.glsl`atm + tileColor.rgb;`:P.glsl`tileColor.rgb;`}

        // heuristic shading function used in the old terrain, now used to add ambient lighting
        float additionalAmbientScale = smoothstep(0.0, 1.0, clamp(vndl${e.shading?"":P.glsl`*2.5`}, 0.0, 1.0));

        vec3 additionalLight = ssao * lightingMainIntensity * additionalAmbientScale * ambientBoostFactor ${e.shading?"":P.glsl`* lightingGlobalFactor`};

        gl_FragColor = vec4(evaluateSceneLighting(normal, albedo, shadow, 1.0 - ssao, additionalLight), tileColor.a);
        ${v?P.glsl`
            vec4 overlayWaterMask = getOverlayColor(ovWaterTex, vtcOverlay);
            float waterNormalLength = length(overlayWaterMask);
            if (waterNormalLength > 0.95) {
              mat3 tbnMatrix = mat3(tbnTangent, tbnBiTangent, vnormal);
              vec4 waterOverlayColor = vec4(overlayColor.w > 0.0 ? overlayColorOpaque.xyz/overlayColor.w : vec3(1.0), overlayColor.w);
              vec4 viewPosition = view*vec4(vpos, 1.0);
              vec4 waterColorLinear = getOverlayWaterColor(overlayWaterMask, waterOverlayColor, -normalize(vpos - cameraPosition), shadow, vnormal, tbnMatrix, viewPosition.xyz,  vpos + origin);
              vec4 waterColorNonLinear = delinearizeGamma(vec4(waterColorLinear.xyz, 1.0));
              // un-gamma the ground color to mix in linear space
              gl_FragColor = mix(groundColor, waterColorNonLinear, waterColorLinear.w);
            }`:""}
        ${e.screenSizePerspective?P.glsl`
          float perspectiveScale = screenSizePerspectiveScaleFloat(1.0, screenSizeCosAngle, screenSizeDistanceToCamera, vec4(0.0, 0.0, 0.0, 0.0));
          if (perspectiveScale <= 0.25) {
            gl_FragColor = mix(gl_FragColor, vec4(1.0, 0.0, 0.0, 1.0), perspectiveScale * 4.0);
          }
          else if (perspectiveScale <= 0.5) {
            gl_FragColor = mix(gl_FragColor, vec4(0.0, 0.0, 1.0, 1.0), (perspectiveScale - 0.25) * 4.0);
          }
          else if (perspectiveScale >= 0.99) {
            gl_FragColor = mix(gl_FragColor, vec4(0.0, 1.0, 0.0, 1.0), 0.2);
          }
          else {
            gl_FragColor = mix(gl_FragColor, vec4(1.0, 0.0, 1.0, 1.0), (perspectiveScale - 0.5) * 2.0);
          }`:""}
        ${e.tileBorders?P.glsl`
            vec2 dVuv = fwidth(vuv);
            vec2 edgeFactors = smoothstep(vec2(0.0), 1.5 * dVuv, min(vuv, 1.0 - vuv));
            float edgeFactor = 1.0 - min(edgeFactors.x, edgeFactors.y);
            gl_FragColor = mix(gl_FragColor, vec4(1.0, 0.0, 0.0, 1.0), edgeFactor);`:""}
        gl_FragColor = highlightSlice(gl_FragColor, vpos);
      }
    `)}return e.output!==t.ShaderOutput.Depth&&e.output!==t.ShaderOutput.Shadow||(r.include(d.Transform,{hasModelTransformation:!1,linearDepth:!0}),r.include(v.OutputDepth,{output:e.output}),r.include(w.NormalUtils,e),r.varyings.add("linearDepth","float"),i.uniforms.add(new C.Float2PassUniform("nearFar",((e,r)=>r.camera.nearFar))),i.code.add(P.glsl`void main(void) {
gl_Position = transformPositionWithDepth(proj, view, position, nearFar, linearDepth);
}`),l.code.add(P.glsl`void main() {
outputDepth(linearDepth);
}`)),e.output===t.ShaderOutput.Normal&&(r.include(d.Transform),r.include(w.NormalUtils,e),r.varyings.add("vnormal","vec3"),r.varyings.add("vpos","vec3"),i.uniforms.add(new O.Matrix4PassUniform("viewNormal",((e,r)=>r.camera.viewInverseTransposeMatrix))),i.code.add(P.glsl`
        void main(void) {
          vec3 normal = ${e.shading?P.glsl`normal`:P.glsl`getLocalUp(position, origin)`};
          vpos = position;

          gl_Position = transformPosition(proj, view, vpos);
          vnormal = normalize((viewNormal * vec4(normal, 1.0)).xyz);
        }
    `),l.code.add(P.glsl`void main() {
vec3 normal = normalize(vnormal);
if (gl_FrontFacing == false) {
normal = -normal;
}
gl_FragColor = vec4(vec3(0.5) + 0.5 * normal, 0.0);
}`)),e.output===t.ShaderOutput.Highlight&&(r.include(d.Transform),r.include(w.NormalUtils,e),r.include(b.OverlayTerrain,e),i.code.add(P.glsl`void main() {
setOverlayVTC(uv0);
gl_Position = transformPosition(proj, view, position);
}`),r.include(c.OutputHighlight),l.code.add(P.glsl`void main() {
vec4 overlayColor = getCombinedOverlayColor();
if (overlayColor.a == 0.0) {
gl_FragColor = vec4(0.0);
return;
}
outputHighlight();
}`)),r}const N=i.create(),$=l.create(),A=Object.freeze(Object.defineProperty({__proto__:null,TerrainPassParameters:z,build:U},Symbol.toStringTag,{value:"Module"}));e.Terrain=A,e.TerrainPassParameters=z,e.build=U}));
