@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
116 lines (105 loc) • 12.3 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.32/esri/copyright.txt for details.
*/
import{translate as e}from"../core/libs/gl-matrix-2/math/mat4.js";import{create as r}from"../core/libs/gl-matrix-2/factories/mat4f64.js";import{n as o,i as a}from"./vec32.js";import{create as i}from"../core/libs/gl-matrix-2/factories/vec3f64.js";import{OverlayContent as l}from"../views/3d/terrain/OverlayContent.js";import{TransparencyMode as t}from"../views/3d/terrain/TransparencyMode.js";import{addLinearDepth as n,addNearFar as s,ForwardLinearDepth as c}from"../views/3d/webgl-engine/core/shaderLibrary/ForwardLinearDepth.glsl.js";import{ShaderOutput as d}from"../views/3d/webgl-engine/core/shaderLibrary/ShaderOutput.js";import{SliceDraw as m}from"../views/3d/webgl-engine/core/shaderLibrary/Slice.glsl.js";import{Transform as v}from"../views/3d/webgl-engine/core/shaderLibrary/Transform.glsl.js";import{NormalAttribute as g}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/NormalAttribute.glsl.js";import{PositionAttribute as p}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/PositionAttribute.glsl.js";import{TextureCoordinateAttribute as f}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/TextureCoordinateAttribute.glsl.js";import{VertexTangent as w}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/VertexTangent.glsl.js";import{OutputDepth as h}from"../views/3d/webgl-engine/core/shaderLibrary/output/OutputDepth.glsl.js";import{OutputHighlight as u}from"../views/3d/webgl-engine/core/shaderLibrary/output/OutputHighlight.glsl.js";import{EvaluateAmbientOcclusion as b}from"../views/3d/webgl-engine/core/shaderLibrary/shading/EvaluateAmbientOcclusion.glsl.js";import{EvaluateSceneLighting as y,addAmbientBoostFactor as C,addLightingGlobalFactor as x}from"../views/3d/webgl-engine/core/shaderLibrary/shading/EvaluateSceneLighting.glsl.js";import{addMainLightDirection as j,addMainLightIntensity as O}from"../views/3d/webgl-engine/core/shaderLibrary/shading/MainLighting.glsl.js";import{NormalUtils as S}from"../views/3d/webgl-engine/core/shaderLibrary/shading/NormalUtils.glsl.js";import{PBRMode as L}from"../views/3d/webgl-engine/core/shaderLibrary/shading/PhysicallyBasedRenderingParameters.glsl.js";import{ReadShadowMapDraw as T}from"../views/3d/webgl-engine/core/shaderLibrary/shading/ReadShadowMap.glsl.js";import{OverlayMode as z,OverlayTerrain as P}from"../views/3d/webgl-engine/core/shaderLibrary/terrain/Overlay.glsl.js";import{OverlayTerrainPassParameters as M,TerrainTexture as $}from"../views/3d/webgl-engine/core/shaderLibrary/terrain/TerrainTexture.glsl.js";import{addProjViewLocalOrigin as N,addViewNormal as D,addCameraPosition as W}from"../views/3d/webgl-engine/core/shaderLibrary/util/View.glsl.js";import{Float3BindUniform as A}from"../views/3d/webgl-engine/core/shaderModules/Float3BindUniform.js";import{glsl as V,If as F}from"../views/3d/webgl-engine/core/shaderModules/glsl.js";import{Matrix4DrawUniform as U}from"../views/3d/webgl-engine/core/shaderModules/Matrix4DrawUniform.js";import{Texture2DPassUniform as _}from"../views/3d/webgl-engine/core/shaderModules/Texture2DPassUniform.js";import{ShaderBuilder as H}from"../views/webgl/ShaderBuilder.js";import{alphaCutoff as B}from"../webscene/support/AlphaCutoff.js";class k extends M{}function E(r){const i=new H,{vertex:M,fragment:k,varyings:E}=i,{output:G,pbrMode:R,overlayMode:J,tileBorders:K,spherical:Q,transparencyMode:X,screenSizePerspective:Y}=r;i.include(p),i.include(g,r),i.include(f,r);const Z=()=>{i.include(S,r),M.code.add(V`vec3 getNormal() {
float z = 1.0 - abs(normalCompressed.x) - abs(normalCompressed.y);
vec3 n = vec3(normalCompressed + vec2(normalCompressed.x >= 0.0 ? 1.0 : -1.0,
normalCompressed.y >= 0.0 ? 1.0 : -1.0) * min(z, 0.0), z);
return normalize(n);
}`)};N(M,r),i.include(v,r);const ee=X===t.InvisibleWithDraped||X===t.Invisible,re=J!==z.Disabled,oe=re&ⅇswitch(G){case d.ColorEmission:case d.Color:{i.include($,r),i.include(y,r),re&&(r.pbrMode=R===L.Simplified?L.TerrainWithWater:L.Water,i.include(P,r),r.pbrMode=R);const t=J===z.EnabledWithWater;t&&i.include(w,r),E.add("vnormal","vec3"),E.add("vpos","vec3"),E.add("vup","vec3"),Z(),Y&&D(M);const n=r.receiveShadows&&!r.renderOccluded;n&&i.include(c,r),Y&&(E.add("screenSizeDistanceToCamera","float"),E.add("screenSizeCosAngle","float")),M.main.add(V`
vpos = position;
vec3 positionWorld = position + localOrigin;
gl_Position = transformPosition(proj, view, vpos);
vnormal = getNormal();
vup = getLocalUp(position, localOrigin);
${F(t,V`forwardVertexTangent(vnormal);`)}
vec2 uv = getUV0();
forwardTextureCoordinatesWithTransform(uv);
${F(re,"setOverlayVTC(uv);")}
${F(K,"forwardTextureCoordinates();")}
${F(Y,V`vec3 viewPos = (view * vec4(vpos, 1.0)).xyz;
screenSizeDistanceToCamera = length(viewPos);
vec3 viewSpaceNormal = (viewNormal * vec4(normalize(positionWorld), 1.0)).xyz;
screenSizeCosAngle = abs(viewSpaceNormal.z);`)}
${F(n,"forwardLinearDepth();")}`),i.fragment.include(m,r),i.include(y,r),i.include(b,r),i.include(T,r),W(k,r),C(k),x(k),k.uniforms.add(M.uniforms.get("localOrigin"),new A("viewDirection",(({camera:e})=>o(q,a(q,e.viewMatrix[12],e.viewMatrix[13],e.viewMatrix[14]))))),t&&k.uniforms.add(new _("ovWaterTex",((e,r)=>r.overlay?.getTexture(l.WaterNormal))),new U("view",(({origin:r},{camera:o})=>e(I,o.viewMatrix,r))));const s=.2;k.code.add(V`float lum(vec3 c) {
return (min(min(c.r, c.g), c.b) + max(max(c.r, c.g), c.b)) * 0.5;
}`),j(k),O(k),k.main.add(V`
vec3 normal = normalize(vnormal);
float vndl = dot(normal, mainLightDirection);
float additionalAmbientScale = smoothstep(0.0, 1.0, clamp(vndl*2.5, 0.0, 1.0));
float shadow = ${n?"max(lightingGlobalFactor * (1.0 - additionalAmbientScale), readShadowMap(vpos, linearDepth))":Q?"lightingGlobalFactor * (1.0 - additionalAmbientScale)":"0.0"};
float ssao = evaluateAmbientOcclusionInverse();
vec4 tileColor = getTileColor();
${F(re,V`vec4 overlayColorOpaque = getOverlayColor(ovColorTex, vtcOverlay);
vec4 overlayColor = overlayOpacity * overlayColorOpaque;
${F(ee,`if (overlayColor.a < ${V.float(B)}) { discard; }`)}
vec4 groundColor = tileColor;
tileColor = tileColor * (1.0 - overlayColor.a) + overlayColor;`)}
// If combined alpha is 0 we can discard pixel. The performance impact by having a discard here
// is neglectable because terrain typically renders first into the framebuffer.
if(tileColor.a < ${V.float(B)}) {
discard;
}
bool sliced = rejectBySlice(vpos);
if (sliced) {
tileColor *= ${V.float(s)};
}
vec3 albedo = tileColor.rgb;
// heuristic shading function used in the old terrain, now used to add ambient lighting
vec3 additionalLight = ssao * mainLightIntensity * additionalAmbientScale * ambientBoostFactor * lightingGlobalFactor;
${R===L.Simplified||R===L.TerrainWithWater?V`fragColor = vec4(evaluatePBRSimplifiedLighting(normal, albedo, shadow, 1.0 - ssao, additionalLight, normalize(vpos - cameraPosition), vup), tileColor.a);`:V`fragColor = vec4(evaluateSceneLighting(normal, albedo, shadow, 1.0 - ssao, additionalLight), tileColor.a);`}
${F(t,V`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 + localOrigin);
vec4 waterColorNonLinear = delinearizeGamma(vec4(waterColorLinear.xyz, 1.0));
float opacity = sliced ? ${V.float(s)} : 1.0;
// un-gamma the ground color to mix in linear space
fragColor = mix(groundColor, waterColorNonLinear, waterColorLinear.w) * opacity;
}`)}
${F(Y,V`float perspectiveScale = screenSizePerspectiveScaleFloat(1.0, screenSizeCosAngle, screenSizeDistanceToCamera, vec4(0.0));
if (perspectiveScale <= 0.25) {
fragColor = mix(fragColor, vec4(1.0, 0.0, 0.0, 1.0), perspectiveScale * 4.0);
} else if (perspectiveScale <= 0.5) {
fragColor = mix(fragColor, vec4(0.0, 0.0, 1.0, 1.0), (perspectiveScale - 0.25) * 4.0);
} else if (perspectiveScale >= 0.99) {
fragColor = mix(fragColor, vec4(0.0, 1.0, 0.0, 1.0), 0.2);
} else {
fragColor = mix(fragColor, vec4(1.0, 0.0, 1.0, 1.0), (perspectiveScale - 0.5) * 2.0);
}`)}
${F(r.visualizeNormals,Q?V`
vec3 localUp = normalize(vpos + localOrigin);
vec3 right = normalize(cross(vec3(0.0, 0.0, 1.0), localUp));
vec3 forward = normalize(cross(localUp, right));
mat3 tbn = mat3(right, forward, localUp);
vec3 tNormal = normalize(normal * tbn);
fragColor = vec4(vec3(0.5) + 0.5 * tNormal, 0.0);`:V`
vec3 tNormal = normalize(normal);
fragColor = vec4(vec3(0.5) + 0.5 * tNormal, 0.0);`)}
${F(K,V`vec2 dVuv = fwidth(vuv0);
vec2 edgeFactors = smoothstep(vec2(0.0), 1.5 * dVuv, min(vuv0, 1.0 - vuv0));
float edgeFactor = 1.0 - min(edgeFactors.x, edgeFactors.y);
fragColor = mix(fragColor, vec4(1.0, 0.0, 0.0, 1.0), edgeFactor);`)}
fragColor = applySlice(fragColor, vpos);`)}break;case d.Depth:oe&&i.include(P,r),M.main.add(V`
${F(oe,"setOverlayVTC(getUV0());")}
gl_Position = transformPosition(proj, view, position);`),k.main.add(`${F(oe,`if (getCombinedOverlayColor().a < ${V.float(B)}) discard;`)}`);break;case d.Shadow:case d.ShadowHighlight:case d.ShadowExcludeHighlight:case d.ViewshedShadow:i.include(h,r),n(i),s(i),M.main.add(V`gl_Position = transformPositionWithDepth(proj, view, position, nearFar, linearDepth);`),k.main.add(V`outputDepth(linearDepth);`);break;case d.Normal:oe&&i.include(P,r),E.add("vnormal","vec3"),D(M),Z(),M.main.add(V`
${F(oe,"setOverlayVTC(getUV0());")}
gl_Position = transformPosition(proj, view, position);
vnormal = normalize((viewNormal * vec4(getNormal(), 1.0)).xyz);`),k.main.add(V`
${F(oe,`if (getCombinedOverlayColor().a < ${V.float(B)}) discard;`)}
vec3 normal = normalize(vnormal);
if (gl_FrontFacing == false) {
normal = -normal;
}
fragColor = vec4(vec3(0.5) + 0.5 * normal, 1.0);`);break;case d.Highlight:re&&i.include(P,r),M.main.add(V`
${F(re,"setOverlayVTC(getUV0());")}
gl_Position = transformPosition(proj, view, position);`),i.include(u,r),k.main.add(V`
${F(re,V`
vec2 overlayHighlightTexel = getAllOverlayHighlightValuesEncoded();
calculateOcclusionAndOutputHighlightOverlay(overlayHighlightTexel);`,"calculateOcclusionAndOutputHighlight();")}
`)}if(G===d.ObjectAndLayerIdColor)if(re)r.pbrMode=L.Disabled,i.include(P,r),r.pbrMode=R,M.main.add(V`gl_Position = transformPosition(proj, view, position);
setOverlayVTC(getUV0());`),k.main.add(V`fragColor = getOverlayColorTexel();`);else{const e=X===t.Opaque;M.main.add(V`${F(e,"gl_Position = transformPosition(proj, view, position);")}`),k.main.add(V`fragColor = vec4(0.0);`)}return i}const I=r(),q=i(),G=Object.freeze(Object.defineProperty({__proto__:null,TerrainPassParameters:k,build:E},Symbol.toStringTag,{value:"Module"}));export{k as T,G as a,E as b};