/* COPYRIGHT Esri - https://js.arcgis.com/5.0.18/LICENSE.txt */
import{ZEROS as e}from"../core/libs/gl-matrix-2/factories/vec3f64.js";import{Colormap as a}from"../views/3d/webgl-engine/core/shaderLibrary/raster/Colormap.glsl.js";import{CommonPassParameters as o,Common as l}from"../views/3d/webgl-engine/core/shaderLibrary/raster/Common.glsl.js";import{TileBackground as r}from"../views/3d/webgl-engine/core/shaderLibrary/terrain/TileBackground.glsl.js";import{TileComposite as i}from"../views/3d/webgl-engine/core/shaderLibrary/terrain/TileComposite.glsl.js";import{ColorConversion as t}from"../views/3d/webgl-engine/core/shaderLibrary/util/ColorConversion.glsl.js";import{BooleanPassUniform as u}from"../views/3d/webgl-engine/core/shaderModules/BooleanPassUniform.js";import{Float2PassUniform as n}from"../views/3d/webgl-engine/core/shaderModules/Float2PassUniform.js";import{Float3PassUniform as s}from"../views/3d/webgl-engine/core/shaderModules/Float3PassUniform.js";import{FloatPassUniform as c}from"../views/3d/webgl-engine/core/shaderModules/FloatPassUniform.js";import{FloatsPassUniform as m}from"../views/3d/webgl-engine/core/shaderModules/FloatsPassUniform.js";import{glsl as f}from"../views/3d/webgl-engine/core/shaderModules/glsl.js";import{IntegerPassUniform as d}from"../views/3d/webgl-engine/core/shaderModules/IntegerPassUniform.js";import{Texture2DPassUniform as g}from"../views/3d/webgl-engine/core/shaderModules/Texture2DPassUniform.js";import{ShaderBuilder as x}from"../views/webgl/ShaderBuilder.js";class p extends o{constructor(a,o,l,r,i,t){super(a,r,i),this.colormap=o,this.symbolizer=l,this.u_colormap=t,this.backgroundColor=e,this.fboTexture=null,this.baseOpacity=1}}class v extends p{}class _ extends p{}function y(e){const o=new x;return o.include(i),o.include(l,e),o.include(a,e),o.include(r,e),o.fragment.code.add(f`vec4 applyBackgroundBlend(vec4 layerColor) {
return blendLayers(vuv, layerColor, u_opacity);
}`),0===e.colorizerType?b(o,e):1===e.colorizerType?h(o):2===e.colorizerType&&C(o,e),o}function h(e){e.fragment.main.add(f`vec2 pixelLocation = getPixelLocation(uv);
if (isOutside(pixelLocation)) {
fragColor = applyBackgroundBlend(vec4(0.0, 0.0, 0.0, 0.0));
return;
}
vec4 currentPixel = getPixel(pixelLocation);
fragColor = applyBackgroundBlend(colormap(currentPixel, true));`)}function b(e,a){e.fragment.uniforms.add(new d("u_bandCount",e=>e.symbolizer.u_bandCount),new s("u_minCutOff",e=>e.symbolizer.u_minCutOff),new s("u_maxCutOff",e=>e.symbolizer.u_maxCutOff),new s("u_factor",e=>e.symbolizer.u_factor),new c("u_minOutput",e=>e.symbolizer.u_minOutput),new c("u_maxOutput",e=>e.symbolizer.u_maxOutput),new u("u_useGamma",e=>e.symbolizer.u_useGamma),new s("u_gamma",e=>e.symbolizer.u_gamma),new s("u_gammaCorrection",e=>e.symbolizer.u_gammaCorrection),new c("u_opacity",e=>e.common.u_opacity)),e.fragment.code.add(f`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?f`fragColor = applyBackgroundBlend(colormap(vec4(grayVal, grayVal, grayVal, currentPixel.a), !u_useGamma));`:f`fragColor = applyBackgroundBlend(vec4(grayVal, grayVal, grayVal, currentPixel.a));`;e.fragment.main.add(f`
    vec2 pixelLocation = getPixelLocation(uv);
    if (isOutside(pixelLocation)) {
      fragColor = applyBackgroundBlend(vec4(0.0, 0.0, 0.0, 0.0));
      return;
    }

    vec4 currentPixel = getPixel(pixelLocation);
    ${0===a.stretchType?f`fragColor = applyBackgroundBlend(currentPixel);`:f`
    if (currentPixel.a == 0.0) {
      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]);
      fragColor = applyBackgroundBlend(vec4(redVal, greenVal, blueVal, currentPixel.a));
    }`}`)}function C(e,a){const o=e.fragment;o.uniforms.add(new g("u_image",e=>e.u_image),new d("u_hillshadeType",e=>e.symbolizer.u_hillshadeType),new m("u_sinZcosAs",6,e=>e.symbolizer.u_sinZcosAs),new m("u_sinZsinAs",6,e=>e.symbolizer.u_sinZsinAs),new m("u_cosZs",6,e=>e.symbolizer.u_cosZs),new m("u_weights",6,e=>e.symbolizer.u_weights),new n("u_factor",e=>e.symbolizer.u_factor),new c("u_minValue",e=>e.symbolizer.u_minValue),new c("u_maxValue",e=>e.symbolizer.u_maxValue),new n("u_srcImageSize",e=>e.common.u_srcImageSize)),o.include(t),o.code.add(f`vec4 overlay(float val, float minValue, float maxValue, float hillshade, float alpha) {
val = clamp((val - minValue) / (maxValue - minValue), 0.0, 1.0);
vec4 color = colormap(vec4(val, val, val, 1.0), false);
vec3 hsv = rgb2hsv(color.rgb);
hsv.z = hillshade;
return vec4(hsv2rgb(hsv), 1.0) * alpha * color.a;
}`),o.code.add(f`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?f`fragColor = applyBackgroundBlend(overlay(ve.r, u_minValue, u_maxValue, hillshade, alpha));`:f`hillshade *= alpha;
fragColor = applyBackgroundBlend(vec4(hillshade, hillshade, hillshade, alpha));`;o.main.add(f`
      vec2 pixelLocation = getPixelLocation(uv);
      if (isOutside(pixelLocation)) {
        fragColor = applyBackgroundBlend(vec4(0.0, 0.0, 0.0, 0.0));
        return;
      }

      vec4 currentPixel = getPixel(pixelLocation);
      if (currentPixel.a == 0.0) {
        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 = texture(u_image, pixelLocation + onePixel * axy);
      vec4 vb = texture(u_image, pixelLocation + onePixel * bxy);
      vec4 vc = texture(u_image, pixelLocation + onePixel * cxy);
      vec4 vd = texture(u_image, pixelLocation + onePixel * dxy);
      vec4 ve = texture(u_image, pixelLocation);
      vec4 vf = texture(u_image, pixelLocation + onePixel * fxy);
      vec4 vg = texture(u_image, pixelLocation + onePixel * gxy);
      vec4 vh = texture(u_image, pixelLocation + onePixel * hxy);
      vec4 vi = texture(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 w=Object.freeze(Object.defineProperty({__proto__:null,ColorizerHillshadeUniforms:_,ColorizerStretchUniforms:v,ColorizerUniforms:p,build:y},Symbol.toStringTag,{value:"Module"}));export{p as C,w as R,_ as a,v as b,y as c};
