@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
155 lines (133 loc) • 13.3 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */
import{ComponentData as e}from"../views/3d/webgl-engine/collections/Component/Material/ComponentData.glsl.js";import{ForwardLinearDepthToWriteShadowMap as o}from"../views/3d/webgl-engine/core/shaderLibrary/ForwardLinearDepthToWriteShadowMap.glsl.js";import{isColor as r,isShadow as a}from"../views/3d/webgl-engine/core/shaderLibrary/ShaderOutput.js";import{SlicePass as l}from"../views/3d/webgl-engine/core/shaderLibrary/Slice.glsl.js";import{TextureCoordinateAttribute as i}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/TextureCoordinateAttribute.glsl.js";import{VertexColor as t}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/VertexColor.glsl.js";import{VertexNormal as n}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/VertexNormal.glsl.js";import{VertexPosition as s}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/VertexPosition.glsl.js";import{OutputDepth as d}from"../views/3d/webgl-engine/core/shaderLibrary/output/OutputDepth.glsl.js";import{OutputHighlight as g}from"../views/3d/webgl-engine/core/shaderLibrary/output/OutputHighlight.glsl.js";import{OutputHighlightOverlay as c}from"../views/3d/webgl-engine/core/shaderLibrary/output/OutputHighlightOverlay.js";import{ReadDepth as m}from"../views/3d/webgl-engine/core/shaderLibrary/output/ReadDepth.glsl.js";import{computeFragmentNormals as v}from"../views/3d/webgl-engine/core/shaderLibrary/shading/ComputeFragmentNormals.glsl.js";import{ComputeMaterialColor as u}from"../views/3d/webgl-engine/core/shaderLibrary/shading/ComputeMaterialColor.glsl.js";import{ComputeNormalTextureDraw as h}from"../views/3d/webgl-engine/core/shaderLibrary/shading/ComputeNormalTexture.glsl.js";import{EvaluateSceneLighting as w,addLightingGlobalFactor as p}from"../views/3d/webgl-engine/core/shaderLibrary/shading/EvaluateSceneLighting.glsl.js";import{addMainLightIntensity as b,addMainLightDirection as f}from"../views/3d/webgl-engine/core/shaderLibrary/shading/MainLighting.glsl.js";import{PhysicallyBasedRenderingParameters as y}from"../views/3d/webgl-engine/core/shaderLibrary/shading/PhysicallyBasedRenderingParameters.glsl.js";import{PiUtils as C}from"../views/3d/webgl-engine/core/shaderLibrary/shading/PiUtils.glsl.js";import{ReadBaseColorTexture as x}from"../views/3d/webgl-engine/core/shaderLibrary/shading/ReadBaseColorTexture.glsl.js";import{ReadShadowMapPass as L}from"../views/3d/webgl-engine/core/shaderLibrary/shading/ReadShadowMap.glsl.js";import{terrainDepthTest as S}from"../views/3d/webgl-engine/core/shaderLibrary/shading/TerrainDepthTest.glsl.js";import{OverlayIM as O}from"../views/3d/webgl-engine/core/shaderLibrary/terrain/Overlay.glsl.js";import{DiscardOrAdjustAlphaDraw as j}from"../views/3d/webgl-engine/core/shaderLibrary/util/DiscardOrAdjustAlpha.glsl.js";import{BooleanDrawUniform as N}from"../views/3d/webgl-engine/core/shaderModules/BooleanDrawUniform.js";import{If as $,glsl as T}from"../views/3d/webgl-engine/core/shaderModules/glsl.js";import{Texture2DBindUniform as D}from"../views/3d/webgl-engine/core/shaderModules/Texture2DBindUniform.js";import{SnowCover as R}from"../views/3d/webgl-engine/effects/weather/SnowCover.glsl.js";import{outputColorHighlightOLID as M}from"../views/3d/webgl-engine/shaders/OutputColorHighlightOLID.glsl.js";import{getPlanetRadius as P,sphereDepthInterpolate as W}from"../views/3d/webgl-engine/shaders/SphereDepthInterpolate.glsl.js";import{ShaderBuilder as A}from"../views/webgl/ShaderBuilder.js";import{alphaCutoff as F}from"../webscene/support/AlphaCutoff.js";function U(U){const V=new A,{vertex:z,fragment:B}=V;V.include(s,U),V.include(n,U),V.include(t,U),V.include(i,U),V.include(e,U),V.include(j,U),B.include(l,U),V.include(x,U),V.include(S,U);const{output:E,pbrMode:_,hasNormalTexture:I,snowCover:G,receiveShadows:H,shadeNormals:k,spherical:q,sphericalSR:J,overlayEnabled:K,componentDataType:Q,vertexDiscardMode:X,renderOccluded:Y,isGroundSlice:Z}=U,ee=1===_||2===_;ee&&(V.include(y,U),I&&V.include(h,U));const oe=a(E),re=oe&&1===Q,ae=P(U);K&&(B.include(w,U),V.include(O,U),z.include(C),z.uniforms.add(new N("useENUForGlobalOverlayUV",e=>e.useENUForGlobalOverlayUV)),B.uniforms.add(new N("useENUForGlobalOverlayUV",e=>e.useENUForGlobalOverlayUV)),z.constants.add("invRadius","float",1/ae).code.add(`vec2 projectOverlay(vec3 pos) { return pos.xy ${$(q,"/ (1.0 + invRadius * pos.z)")}; }`));const le=K&&r(E)&&4===_;le&&(V.varyings.add("tbnTangent","vec3"),V.varyings.add("tbnBiTangent","vec3"),V.varyings.add("groundNormal","vec3"));const ie=0===X,te=2===X,ne=1-1/255;if(V.include(L,U),V.include(o,U),z.main.add(T`
bool castShadows;
vec4 externalColor = forwardExternalColor(castShadows);
${$(re,"if(!castShadows) { gl_Position = vec4(vec3(1e38), 1.0); return; }")}
${$(!ie,`{ if (externalColor.a ${te?">":"<="} ${T.float(ne)}) { gl_Position = vec4(vec3(1e38), 1.0); return; } }`)}
${$(9===E,"externalColor.a = 1.0;")}
forwardPosition(readElevationOffset());
forwardViewPosDepth(vPosition_view);
forwardNormal();
forwardTextureCoordinates();
forwardVertexColor();
forwardLinearDepthToReadShadowMap();
forwardLinearDepthToWriteShadowMap();
forwardEmissiveStrength();
forwardObjectAndLayerIdColor();
${$(le,q?T`
groundNormal = normalize(positionWorld());
tbnTangent = normalize(cross(vec3(0.0, 0.0, 1.0), groundNormal));
tbnBiTangent = normalize(cross(groundNormal, tbnTangent));`:T`
groundNormal = vec3(0.0, 0.0, 1.0);
tbnTangent = vec3(1.0, 0.0, 0.0);
tbnBiTangent = vec3(0.0, 1.0, 0.0);`)}
${$(K,$(q,"\n if (useENUForGlobalOverlayUV) {\n setOverlayVTC(projectOverlay(position));\n } else {\n vtcOverlay = vec4(0.0); // Definite assignment\n }\n ","setOverlayVTC(projectOverlay(position));"))}
if (externalColor.a < ${T.float(F)}) {
// Discard this vertex
gl_Position = vec4(1e38, 1e38, 1e38, 1.0);
return;
}
`),r(E))return V.include(u,U),V.include(v,U),B.include(w,U),V.include(M,U),B.include(R,U),B.constants.add("pRadius","float",ae).code.add(T`
float evaluateShadow() {
return ${H?"readShadowMap(vPositionWorldCameraRelative, linearDepth)":"0.0"};
}
`).main.add(T`
${$(!Z,"discardBySlice(vPositionWorldCameraRelative);")}
discardByTerrainDepth();
vec4 textureColor = readBaseColorTexture();
discardOrAdjustAlpha(textureColor);
// When rendering the occluded overlay, we still need to read the base color texture because we need to use the
// same discard logic. However after that to render only the draped overlay, we simply set the base texture color
// to zero.
${$(Y,T`textureColor = vec4(0);`)}
${$(K,T`
${$(q,T`
vec4 overlayUVs;
if (useENUForGlobalOverlayUV) {
overlayUVs = vtcOverlay;
} else {
const float rad2deg1 = 180.0 / PI;
vec3 wPos = positionWorld();
float oRadius = length(wPos.xyz);
float oLonRad = atan(wPos.y, wPos.x);
float sinLat = wPos.z / oRadius;
${$(1===J,T`
const float halfSemiMajorAxis = 0.5 * pRadius;
vec2 posWM = vec2(
oLonRad * pRadius,
halfSemiMajorAxis * log((1.0 + sinLat) / (1.0 - sinLat))
);
vec2 overlayUV = posWM;
`,T`
float oLatRad = asin(clamp(sinLat,-1.0,1.0));
vec2 posWgs84 = vec2(rad2deg1 * oLonRad, rad2deg1 * oLatRad);
vec2 overlayUV = posWgs84;
`)}
overlayUVs = vec4(overlayUV, overlayUV) * overlayTexScale + overlayTexOffset;
}
`,T`vec4 overlayUVs = vtcOverlay;`)}
vec4 overlayColor = getOverlayColor(ovColorTex, overlayUVs);
/* Early discard to only emit when we have overlay */
${$(Y,T`if (overlayColor.a < ${T.float(F)}) { discard; }`)}
`)}
vec4 externalColor;
int externalColorMixMode;
readExternalColor(externalColor, externalColorMixMode);
vec4 materialColor = computeMaterialColor(textureColor, externalColor, externalColorMixMode);
`),ee?(b(B),q&&p(B),B.main.add(T`
applyPBRFactors();
${$(1===_,T`if (externalColorMixMode == 3) {
mrr = vec3(0.0, 0.6, 0.2);
}`)}
float additionalIrradiance = 0.02 * mainLightIntensity[2];
${$(I,"mat3 tangentSpace = computeTangentSpace(fragmentFaceNormal, vPositionWorldCameraRelative, vuv0);")}
vec3 shadingNormal = ${I?"computeTextureNormal(tangentSpace, vuv0)":"fragmentShadingNormal"};
vec3 groundNormal = ${q?T`normalize(positionWorld())`:T`vec3(0.0, 0.0, 1.0)`};
vec3 viewDir = normalize(vPositionWorldCameraRelative);
float ssao = 1.0 - occlusion * evaluateAmbientOcclusionInverse();
${$(G,T`float snow = getSnow(fragmentFaceNormal, normalize(positionWorld()));
materialColor.rgb = mix(materialColor.rgb, vec3(1.1), snow);
ssao = mix(ssao, 0.5 * ssao, snow);
shadingNormal = mix(shadingNormal, fragmentFaceNormal, snow);`)}
${$(K,"materialColor = materialColor * (1.0 - overlayColor.a) + overlayColor;")}
vec3 additionalLight = evaluateAdditionalLighting(ssao, positionWorld());
${$(q,"float additionalAmbientScale = additionalDirectedAmbientLight(positionWorld());")}
${q?T`float shadow = max(lightingGlobalFactor * (1.0 - additionalAmbientScale), evaluateShadow());`:"float shadow = evaluateShadow();"}
vec4 shadedColor = vec4(evaluateSceneLightingPBR(shadingNormal, materialColor.rgb, shadow, ssao, additionalLight, viewDir, groundNormal, mrr, additionalIrradiance), materialColor.a);
`)):(f(B),q&&p(B),le&&B.uniforms.add(new D("ovNormalTex",e=>e.overlay?.getTexture(3))),B.main.add(T`
${$(q,"float additionalAmbientScale = additionalDirectedAmbientLight(positionWorld());")}
float shadow = ${H?q?"max(lightingGlobalFactor * (1.0 - additionalAmbientScale), evaluateShadow())":"evaluateShadow()":q?"lightingGlobalFactor * (1.0 - additionalAmbientScale)":"0.0"};
${$(H&&!k,T`
float dotFL = dot(fragmentFaceNormal, mainLightDirection);
if( dotFL <= 0.0) shadow = 1.0;
`)}
${$(G,T`float snow = getSnow(fragmentFaceNormal, normalize(positionWorld()));
materialColor.rgb = mix(materialColor.rgb, vec3(1), snow);`)}
// At global scale we create some additional ambient light based on the main light to simulate global illumination
float ssao = evaluateAmbientOcclusion();
vec3 additionalLight = evaluateAdditionalLighting(ssao, positionWorld());
${$(K,"materialColor = materialColor * (1.0 - overlayColor.a) + overlayColor;")}
vec4 shadedColor = vec4(evaluateSceneLighting(fragmentShadingNormal, materialColor.rgb, shadow, ssao, additionalLight), materialColor.a);
${$(le,T`vec4 overlayWaterMask = getOverlayColor(ovNormalTex, vtcOverlay);
float waterNormalLength = length(overlayWaterMask);
if (waterNormalLength > 0.95) {
mat3 tbnMatrix = mat3(tbnTangent, tbnBiTangent, groundNormal);
vec4 waterColorLinear = getOverlayWaterColor(overlayWaterMask, overlayColor, -normalize(vPositionWorldCameraRelative), shadow, groundNormal, tbnMatrix, vPosition_view, positionWorld());
vec4 waterColorNonLinear = delinearizeGamma(vec4(waterColorLinear.xyz, 1.0));
// un-gamma the ground color to mix in linear space
shadedColor = mix(shadedColor, waterColorNonLinear, waterColorLinear.w);
}`)}
`)),B.main.add(`\n ${$(Z,"if(rejectBySlice(vPositionWorldCameraRelative)) shadedColor.a *= groundSliceOpacity;")}\n\n outputColorHighlightOLID(applySlice(shadedColor, vPositionWorldCameraRelative), materialColor.rgb ${$(G,", snow")});\n `),U.sphereDepthInterpolate&&(V.include(W,U),V.fragment.include(m),B.main.add(T`if (sphereFade()>0.0) {
vec3 worldRay = normalize(vPositionWorldCameraRelative);
vec3 viewRay = normalize(vPosition_view);
gl_FragDepth = delinearizeDepth(sphereDepthInterpolate(worldRay, viewRay, linearizeDepth(gl_FragCoord.z)));
} else {
gl_FragDepth = gl_FragCoord.z;
}`)),V;const se=2===E,de=9===E,ge=8===E,ce=oe||6===E||7===E;return ce&&V.include(d,U),se&&V.include(v,U),K&&V.include(c,U),V.include(g,U),B.main.add(T`
${$(!Z,"discardBySlice(vPositionWorldCameraRelative);")}
vec4 textureColor = readBaseColorTexture();
discardOrAdjustAlpha(textureColor);
${$(ce,"outputDepth(linearDepth);")}
${$(se,T`fragColor = vec4(vec3(0.5) + 0.5 * fragmentFaceNormalView, 1.0);`)}
${$(de,K?"fragColor = getOverlayColorTexel();":"outputObjectAndLayerIdColor();")}
${$(ge,$(K,T`calculateOcclusionAndOutputHighlight(getAllOverlayHighlightValuesEncoded());`,T`calculateOcclusionAndOutputHighlight();`))}`),V}const V=Object.freeze(Object.defineProperty({__proto__:null,build:U},Symbol.toStringTag,{value:"Module"}));export{V as C,U as b};