UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

145 lines (137 loc) • 9.47 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.19/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};