/*
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","../core/maybe","./vec3f64","../views/2d/engine/imagery/enums","../views/3d/webgl-engine/core/shaderLibrary/output/BlendOptions","../views/3d/webgl-engine/core/shaderLibrary/raster/Colormap.glsl","../views/3d/webgl-engine/core/shaderLibrary/raster/Common.glsl","../views/3d/webgl-engine/core/shaderLibrary/terrain/BackgroundGrid.glsl","../views/3d/webgl-engine/core/shaderLibrary/terrain/TileBlendInput","../views/3d/webgl-engine/core/shaderLibrary/terrain/TileComposite.glsl","./BlendLayers.glsl","../views/3d/webgl-engine/core/shaderLibrary/util/BlendModes.glsl","../views/3d/webgl-engine/core/shaderLibrary/util/ColorConversion.glsl","../views/3d/webgl-engine/core/shaderModules/BooleanPassUniform","../views/3d/webgl-engine/core/shaderModules/Float2PassUniform","../views/3d/webgl-engine/core/shaderModules/Float3PassUniform","../views/3d/webgl-engine/core/shaderModules/FloatPassUniform","../views/3d/webgl-engine/core/shaderModules/FloatsPassUniform","../views/3d/webgl-engine/core/shaderModules/IntegerPassUniform","../views/3d/webgl-engine/core/shaderModules/interfaces","../views/3d/webgl-engine/core/shaderModules/ShaderBuilder","../views/3d/webgl-engine/core/shaderModules/Texture2DPassUniform"],(function(e,a,o,l,r,i,t,n,s,u,c,m,d,g,f,p,x,y,v,_,h,b,C){"use strict";let O=function(e){function o(a,o,r,i,t,n){var s;return(s=e.call(this,a,i,t)||this).colormap=o,s.symbolizer=r,s.u_colormap=n,s.backgroundColor=l.ZEROS,s.fboTexture=null,s.baseOpacity=1,s}return a._inheritsLoose(o,e),o}(n.CommonPassParameters),P=function(e){function o(){return e.apply(this,arguments)||this}return a._inheritsLoose(o,e),o}(O),w=function(e){function o(){return e.apply(this,arguments)||this}return a._inheritsLoose(o,e),o}(O);function z(e){const a=new b.ShaderBuilder;a.include(c.TileComposite),a.include(n.Common),a.include(t.Colormap),e.tileBlendInput===u.TileBlendInput.GridComposite&&(a.extensions.add("GL_OES_standard_derivatives"),a.fragment.include(s.BackgroundGrid));const l=e.tileBlendInput===u.TileBlendInput.ColorComposite;l&&a.fragment.uniforms.add(new x.Float3PassUniform("backgroundColor",(e=>e.backgroundColor))),e.baseOpacityMode!==m.BaseOpacityMode.One&&a.fragment.uniforms.add(new y.FloatPassUniform("baseOpacity",(e=>e.baseOpacity)));const g=e.baseOpacityMode===m.BaseOpacityMode.OnBaseLayer,f=e.baseOpacityMode===m.BaseOpacityMode.OnBackground||e.baseOpacityMode===m.BaseOpacityMode.OnBaseLayer,p=e.blendMode!==i.LayerBlendMode.Normal;a.fragment.include(d.BlendModes,e);const v=e.tileBlendInput!==u.TileBlendInput.LayerOnly;return(p&&!v||g)&&(a.fragment.uniforms.add(new C.Texture2DPassUniform("fboColor",(e=>e.fboTexture))),a.fragment.uniforms.add(new y.FloatPassUniform("tileSize",(e=>o.isSome(e.fboTexture)?e.fboTexture.descriptor.width:1)))),a.fragment.code.add(h.glsl`
    vec4 applyBackgroundBlend(vec4 layerColor) {
      ${v||g?h.glsl`
          vec4 bgColor = ${g?h.glsl`texture2D(fboColor, gl_FragCoord.xy / tileSize)`:l?h.glsl`vec4(backgroundColor, 1.0)`:h.glsl`gridColor(vuv)`};
          ${f?h.glsl`bgColor *= baseOpacity;`:""}`:""}
      ${p?h.glsl`
            vec3 pmColorLayer = layerColor.rgb * layerColor.a;
            vec4 fboTex = ${v?h.glsl`bgColor;`:h.glsl`texture2D(fboColor, gl_FragCoord.xy / tileSize) ${g?" * baseOpacity":""};`}
            vec3 Cb = fboTex.a == 0.0 ? fboTex.rgb : vec3(fboTex.rgb * fboTex.a);
            return applyBlendMode(pmColorLayer.rgb, layerColor.a * u_opacity, Cb, fboTex.a);`:v||g?h.glsl`
            float composeAlpha = layerColor.a * u_opacity;
            vec4 pmColorLayer = vec4(layerColor.rgb, 1.0);
            return mix(bgColor, pmColorLayer, composeAlpha);`:h.glsl`
            return layerColor * layerColor.a * u_opacity;`}
    }
  `),e.colorizerType===r.RasterColorizerType.Stretch?L(a,e):e.colorizerType===r.RasterColorizerType.Lut?B(a):e.colorizerType===r.RasterColorizerType.Hillshade&&F(a,e),a}function B(e){e.fragment.code.add(h.glsl`void main() {
vec2 pixelLocation = getPixelLocation(uv);
if (isOutside(pixelLocation)) {
gl_FragColor = applyBackgroundBlend(vec4(0.0, 0.0, 0.0, 0.0));
return;
}
vec4 currentPixel = getPixel(pixelLocation);
gl_FragColor = applyBackgroundBlend(colormap(currentPixel, true));
}`)}function L(e,a){e.fragment.uniforms.add([new _.IntegerPassUniform("u_bandCount",(e=>e.symbolizer.u_bandCount)),new v.FloatsPassUniform("u_minCutOff",(e=>e.symbolizer.u_minCutOff),3),new v.FloatsPassUniform("u_maxCutOff",(e=>e.symbolizer.u_maxCutOff),3),new v.FloatsPassUniform("u_factor",(e=>e.symbolizer.u_factor),3),new y.FloatPassUniform("u_minOutput",(e=>e.symbolizer.u_minOutput)),new y.FloatPassUniform("u_maxOutput",(e=>e.symbolizer.u_maxOutput)),new f.BooleanPassUniform("u_useGamma",(e=>e.symbolizer.u_useGamma)),new v.FloatsPassUniform("u_gamma",(e=>e.symbolizer.u_gamma),3),new v.FloatsPassUniform("u_gammaCorrection",(e=>e.symbolizer.u_gammaCorrection),3),new y.FloatPassUniform("u_opacity",(e=>e.common.u_opacity))]),e.fragment.code.add(h.glsl`float stretchOneValue(float val, float minCutOff, float maxCutOff, float minOutput, float maxOutput, float factor, bool useGamma, float gamma, float gammaCorrection) {
if (val >= maxCutOff) {
return maxOutput;
} else if (val <= minCutOff) {
return minOutput;
}
float stretchedVal;
if (useGamma) {
float tempf = 1.0;
float outRange = maxOutput - minOutput;
float relativeVal = (val - minCutOff) / (maxCutOff - minCutOff);
if (gamma > 1.0) {
tempf -= pow(1.0 / outRange, relativeVal * gammaCorrection);
}
stretchedVal = (tempf * outRange * pow(relativeVal, 1.0 / gamma) + minOutput) / 255.0;
} else {
stretchedVal = minOutput + (val - minCutOff) * factor;
}
return stretchedVal;
}`);const o=a.applyColormap?h.glsl`gl_FragColor = applyBackgroundBlend(colormap(vec4(grayVal, grayVal, grayVal, currentPixel.a), !u_useGamma));`:h.glsl`gl_FragColor = applyBackgroundBlend(vec4(grayVal, grayVal, grayVal, currentPixel.a));`;e.fragment.code.add(h.glsl`
      void main() {
        vec2 pixelLocation = getPixelLocation(uv);
        if (isOutside(pixelLocation)) {
          gl_FragColor = applyBackgroundBlend(vec4(0.0, 0.0, 0.0, 0.0));
          return;
        }

        vec4 currentPixel = getPixel(pixelLocation);
        ${a.stretchType===r.RasterColorizerStretchType.Noop?h.glsl`
        gl_FragColor = applyBackgroundBlend(currentPixel);`:h.glsl`
        if (currentPixel.a == 0.0) {
          gl_FragColor = applyBackgroundBlend(vec4(0.0, 0.0, 0.0, 0.0));
          return;
        }
        if (u_bandCount == 1) {
          float grayVal = stretchOneValue(currentPixel.r, u_minCutOff[0], u_maxCutOff[0], u_minOutput, u_maxOutput, u_factor[0], u_useGamma, u_gamma[0], u_gammaCorrection[0]);
          ${o}
        } else {
          float redVal = stretchOneValue(currentPixel.r, u_minCutOff[0], u_maxCutOff[0], u_minOutput, u_maxOutput, u_factor[0], u_useGamma, u_gamma[0], u_gammaCorrection[0]);
          float greenVal = stretchOneValue(currentPixel.g, u_minCutOff[1], u_maxCutOff[1], u_minOutput, u_maxOutput, u_factor[1], u_useGamma, u_gamma[1], u_gammaCorrection[1]);
          float blueVal = stretchOneValue(currentPixel.b, u_minCutOff[2], u_maxCutOff[2], u_minOutput, u_maxOutput, u_factor[2], u_useGamma, u_gamma[2], u_gammaCorrection[2]);
          gl_FragColor = applyBackgroundBlend(vec4(redVal, greenVal, blueVal, currentPixel.a));
        }`}
      }`)}function F(e,a){const o=e.fragment;o.uniforms.add([new C.Texture2DPassUniform("u_image",(e=>e.u_image)),new _.IntegerPassUniform("u_hillshadeType",(e=>e.symbolizer.u_hillshadeType)),new v.FloatsPassUniform("u_sinZcosAs",(e=>e.symbolizer.u_sinZcosAs),6),new v.FloatsPassUniform("u_sinZsinAs",(e=>e.symbolizer.u_sinZsinAs),6),new v.FloatsPassUniform("u_cosZs",(e=>e.symbolizer.u_cosZs),6),new v.FloatsPassUniform("u_weights",(e=>e.symbolizer.u_weights),6),new p.Float2PassUniform("u_factor",(e=>e.symbolizer.u_factor)),new y.FloatPassUniform("u_minValue",(e=>e.symbolizer.u_minValue)),new y.FloatPassUniform("u_maxValue",(e=>e.symbolizer.u_maxValue)),new p.Float2PassUniform("u_srcImageSize",(e=>e.common.u_srcImageSize))]),o.include(g.ColorConversion),o.code.add(h.glsl`vec4 overlay(float val, float minValue, float maxValue, float hillshade, float alpha) {
val = clamp((val - minValue) / (maxValue - minValue), 0.0, 1.0);
vec3 hsv = rgb2hsv(colormap(vec4(val, val, val, 1.0), false).rgb);
hsv.z = hillshade;
return vec4(hsv2rgb(hsv) * alpha, alpha);
}`),o.code.add(h.glsl`float getNeighborHoodAlpha(float a, float b, float c, float d, float e, float f, float g, float h, float i){
if (a == 0.0 || a == 0.0 || a==0.0 || a == 0.0 || a == 0.0 || a==0.0 || a == 0.0 || a == 0.0 || a==0.0) {
return 0.0;
}  else {
return e;
}
}`);const l=a.applyColormap?h.glsl`gl_FragColor = applyBackgroundBlend(overlay(ve.r, u_minValue, u_maxValue, hillshade, alpha));`:h.glsl`hillshade *= alpha;
gl_FragColor = applyBackgroundBlend(vec4(hillshade, hillshade, hillshade, alpha));`;o.code.add(h.glsl`
    void main() {
      vec2 pixelLocation = getPixelLocation(uv);
      if (isOutside(pixelLocation)) {
        gl_FragColor = applyBackgroundBlend(vec4(0.0, 0.0, 0.0, 0.0));
        return;
      }

      vec4 currentPixel = getPixel(pixelLocation);
      if (currentPixel.a == 0.0) {
        gl_FragColor = applyBackgroundBlend(vec4(0.0, 0.0, 0.0, 0.0));
        return;
      }

      //mirror edge pixels
      vec2 axy = vec2(-1.0, -1.0);
      vec2 bxy = vec2(0.0, -1.0);
      vec2 cxy = vec2(1.0, -1.0);
      vec2 dxy = vec2(-1.0, 0.0);
      vec2 fxy = vec2(1.0, 0.0);
      vec2 gxy = vec2(-1.0, 1.0);
      vec2 hxy = vec2(0.0, 1.0);
      vec2 ixy = vec2(1.0, 1.0);
      vec2 onePixel = 1.0 / u_srcImageSize;
      if (pixelLocation.s < onePixel.s) {
        axy[0] = 1.0;
        dxy[0] = 1.0;
        gxy[0] = 1.0;
      }
      if (pixelLocation.t < onePixel.t) {
        axy[1] = 1.0;
        bxy[1] = 1.0;
        cxy[1] = 1.0;
      }
      if (pixelLocation.s > 1.0 - onePixel.s) {
        cxy[0] = -1.0;
        fxy[0] = -1.0;
        ixy[0] = -1.0;
      }
      if (pixelLocation.t > 1.0 - onePixel.t) {
        gxy[1] = -1.0;
        hxy[1] = -1.0;
        ixy[1] = -1.0;
      }

      // calculate hillshade
      vec4 va = texture2D(u_image, pixelLocation + onePixel * axy);
      vec4 vb = texture2D(u_image, pixelLocation + onePixel * bxy);
      vec4 vc = texture2D(u_image, pixelLocation + onePixel * cxy);
      vec4 vd = texture2D(u_image, pixelLocation + onePixel * dxy);
      vec4 ve = texture2D(u_image, pixelLocation);
      vec4 vf = texture2D(u_image, pixelLocation + onePixel * fxy);
      vec4 vg = texture2D(u_image, pixelLocation + onePixel * gxy);
      vec4 vh = texture2D(u_image, pixelLocation + onePixel * hxy);
      vec4 vi = texture2D(u_image, pixelLocation + onePixel * ixy);

      // calculate the rate of z change along the x, y, and diagonal direction
      float dzx = (vc + 2.0 * vf + vi - va - 2.0 * vd - vg).r * u_factor.s;
      float dzy = (vg + 2.0 * vh + vi - va - 2.0 * vb - vc).r * u_factor.t;
      float dzd = sqrt(1.0 + dzx * dzx + dzy * dzy);
      float hillshade = 0.0;

      // traditional single light source
      if (u_hillshadeType == 0){
        float cosDelta = u_sinZsinAs[0] * dzy - u_sinZcosAs[0] * dzx;
        float z = (u_cosZs[0] + cosDelta) / dzd;
        if (z < 0.0)  z = 0.0;
        hillshade = z;
      } else {
        // multi-directional with 6 light sources
        for (int k = 0; k < 6; k++) {
        float cosDelta = u_sinZsinAs[k] * dzy - u_sinZcosAs[k] * dzx;
        float z = (u_cosZs[k] + cosDelta) / dzd;
        if (z < 0.0) z = 0.0;
        hillshade = hillshade + z * u_weights[k];
        if (k == 5) break;
        }
      }

      // set color
      float alpha = getNeighborHoodAlpha(va.a, vb.a, vc.a, vd.a, ve.a, vf.a, vg.a, vh.a, vi.a);
      alpha *= u_opacity;
      ${l}
    }
  `)}const U=Object.freeze(Object.defineProperty({__proto__:null,ColorizerUniforms:O,ColorizerStretchUniforms:P,ColorizerHillshadeUniforms:w,build:z},Symbol.toStringTag,{value:"Module"}));e.ColorizerHillshadeUniforms=w,e.ColorizerStretchUniforms=P,e.ColorizerUniforms=O,e.RasterColorizer=U,e.build=z}));
