UNPKG

@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
/* 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&&ee;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};