Terrain.glsl.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. All material copyright ESRI, All Rights Reserved, unless otherwise specified.
  3. See https://js.arcgis.com/4.25/esri/copyright.txt for details.
  4. */
  5. import{v as e}from"./mat4.js";import{c as r}from"./mat4f64.js";import{n as o,s as a}from"./vec3.js";import{c as i}from"./vec3f64.js";import{OverlayIndex as l}from"../views/3d/terrain/interfaces.js";import{addLinearDepth as t,addNearFar as n,ForwardLinearDepth as s}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 c}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 m}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/NormalAttribute.glsl.js";import{PositionAttribute as g}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/PositionAttribute.glsl.js";import{TextureCoordinateAttribute as p}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 f,addAmbientBoostFactor as y,addLightingGlobalFactor as C}from"../views/3d/webgl-engine/core/shaderLibrary/shading/EvaluateSceneLighting.glsl.js";import{addMainLightDirection as x,addMainLightIntensity as S}from"../views/3d/webgl-engine/core/shaderLibrary/shading/MainLighting.glsl.js";import{NormalUtils as L}from"../views/3d/webgl-engine/core/shaderLibrary/shading/NormalUtils.glsl.js";import{PBRMode as j}from"../views/3d/webgl-engine/core/shaderLibrary/shading/PhysicallyBasedRenderingParameters.glsl.js";import{ReadShadowMapDraw as z}from"../views/3d/webgl-engine/core/shaderLibrary/shading/ReadShadowMap.glsl.js";import{OverlayMode as O}from"../views/3d/webgl-engine/core/shaderLibrary/terrain/Overlay.glsl.js";import{OverlayTerrainPassParameters as _,OverlayTerrain as F,TerrainTexture as T}from"../views/3d/webgl-engine/core/shaderLibrary/terrain/TerrainTexture.glsl.js";import{addProjViewLocalOrigin as P,addViewNormal as N,addCameraPosition as D}from"../views/3d/webgl-engine/core/shaderLibrary/util/View.glsl.js";import{textureSize as M,texelFetch as $}from"../views/3d/webgl-engine/core/shaderLibrary/util/WebGL2Utils.js";import{Float3PassUniform as W}from"../views/3d/webgl-engine/core/shaderModules/Float3PassUniform.js";import{glsl as U}from"../views/3d/webgl-engine/core/shaderModules/interfaces.js";import{Matrix4DrawUniform as V}from"../views/3d/webgl-engine/core/shaderModules/Matrix4DrawUniform.js";import{ShaderBuilder as A}from"../views/3d/webgl-engine/core/shaderModules/ShaderBuilder.js";import{Texture2DPassUniform as k}from"../views/3d/webgl-engine/core/shaderModules/Texture2DPassUniform.js";class B extends _{}function E(r){const i=new A,{vertex:_,fragment:B,varyings:E}=i;i.include(g),i.include(m,r),i.include(p,r);const I=()=>{i.include(L,r),_.code.add(U`
  6. vec3 decodeNormalTerrain(vec2 e) {
  7. float z = 1.0 - abs(e.x) - abs(e.y);
  8. vec3 n = vec3(e + vec2(e.x >= 0.0 ? 1.0 : -1.0, e.y >= 0.0 ? 1.0 : -1.0) * min(z,0.0),z);
  9. return normalize(n);
  10. }
  11. vec3 getNormal() {
  12. return ${r.shading?U`normalize(decodeNormalTerrain(normalCompressed))`:U`getLocalUp(position, localOrigin)`};
  13. }
  14. `)};P(_,r),i.include(v,r);const q=r.overlayMode!==O.Disabled;switch(r.output){case d.Color:{i.include(T,r),i.include(f,r);const t=r.overlayMode===O.EnabledWithWater;q&&i.include(F,{...r,pbrMode:j.Water}),t&&i.include(w,r),E.add("vnormal","vec3"),E.add("vpos","vec3"),I(),(r.atmosphere||r.screenSizePerspective)&&N(_);const n=r.receiveShadows&&!r.renderOccluded;n&&i.include(s,r),r.atmosphere&&E.add("wnormal","vec3"),r.screenSizePerspective&&(E.add("screenSizeDistanceToCamera","float"),E.add("screenSizeCosAngle","float")),_.code.add(U`
  15. void main(void) {
  16. //Position
  17. vpos = position;
  18. vec3 positionWorld = position + localOrigin;
  19. gl_Position = transformPosition(proj, view, vpos);
  20. //Normal
  21. vnormal = getNormal();
  22. ${t?U`forwardVertexTangent(vnormal);`:U``}
  23. ${r.atmosphere?U`
  24. wnormal = normalize((viewNormal * vec4(normalize(positionWorld), 1.0)).xyz);`:""}
  25. //Texture UV
  26. vec2 uv = getUV0();
  27. forwardTextureCoordinatesWithTransform(uv);
  28. ${q?U`setOverlayVTC(uv);`:""}
  29. ${r.tileBorders?U`forwardTextureCoordinates();`:""}
  30. ${r.screenSizePerspective?U`
  31. vec3 viewPos = (view * vec4(vpos, 1.0)).xyz;
  32. screenSizeDistanceToCamera = length(viewPos);
  33. vec3 viewSpaceNormal = (viewNormal * vec4(normalize(positionWorld), 1.0)).xyz;
  34. screenSizeCosAngle = abs(viewSpaceNormal.z);`:""}
  35. ${n?U`forwardLinearDepth();`:""}
  36. }
  37. `),i.extensions.add("GL_OES_standard_derivatives"),i.extensions.add("GL_EXT_shader_texture_lod"),i.include(c,r),i.include(f,r),i.include(b,r),i.include(z,r),t&&D(B,r),y(B),C(B),B.uniforms.add([_.uniforms.get("localOrigin"),new W("viewDirection",((e,r)=>o(H,a(H,r.camera.viewMatrix[12],r.camera.viewMatrix[13],r.camera.viewMatrix[14]))))]),t&&B.uniforms.add([new k("ovWaterTex",((e,r)=>0===r.overlays.length?null:r.overlays[l.INNER].getNormalTexture(e.overlaySource))),new V("view",((r,o)=>e(G,o.camera.viewMatrix,r.origin)))]),B.code.add(U`const float sliceOpacity = 0.2;
  38. float lum(vec3 c) {
  39. return (min(min(c.r, c.g), c.b) + max(max(c.r, c.g), c.b)) * 0.5;
  40. }`),x(B),S(B),B.code.add(U`
  41. void main() {
  42. vec3 normal = normalize(vnormal);
  43. float vndl = dot(normal, mainLightDirection);
  44. float additionalAmbientScale = smoothstep(0.0, 1.0, clamp(vndl*2.5, 0.0, 1.0));
  45. float shadow = ${r.receiveShadows&&!r.renderOccluded?"readShadowMap(vpos, linearDepth)":r.spherical&&r.shading?"lightingGlobalFactor * (1.0 - additionalAmbientScale)":"0.0"};
  46. float ssao = evaluateAmbientOcclusionInverse();
  47. vec4 tileColor = getTileColor();
  48. ${q?U`
  49. vec4 overlayColorOpaque = getOverlayColor(ovColorTex, vtcOverlay);
  50. vec4 overlayColor = overlayOpacity * overlayColorOpaque;
  51. ${r.transparent?U`if (overlayColor.a == 0.0) { discard; }`:""}
  52. vec4 groundColor = tileColor;
  53. tileColor = tileColor * (1.0 - overlayColor.a) + overlayColor;`:""}
  54. if (rejectBySlice(vpos)) {
  55. tileColor *= sliceOpacity;
  56. }
  57. ${r.atmosphere?U`
  58. float ndotl = clamp(vndl, 0.0, 1.0);
  59. vec3 atm = vec3(clamp(1.0 - dot(-viewDirection, wnormal), 0.0, 1.0));
  60. atm *= clamp(1.0 - lum(tileColor.rgb) * 1.5, 0.0, 1.0); // avoid atmosphere on bright base maps
  61. atm *= clamp(ndotl * 2.0, 0.0, 1.0); // avoid atmosphere on dark side of the globe
  62. atm *= tileColor.a; // premultiply with tile alpha`:""}
  63. vec3 albedo = ${r.atmosphere?U`atm + tileColor.rgb;`:U`tileColor.rgb;`}
  64. // heuristic shading function used in the old terrain, now used to add ambient lighting
  65. vec3 additionalLight = ssao * mainLightIntensity * additionalAmbientScale * ambientBoostFactor * lightingGlobalFactor;
  66. gl_FragColor = vec4(evaluateSceneLighting(normal, albedo, shadow, 1.0 - ssao, additionalLight), tileColor.a);
  67. ${t?U`
  68. vec4 overlayWaterMask = getOverlayColor(ovWaterTex, vtcOverlay);
  69. float waterNormalLength = length(overlayWaterMask);
  70. if (waterNormalLength > 0.95) {
  71. mat3 tbnMatrix = mat3(tbnTangent, tbnBiTangent, vnormal);
  72. vec4 waterOverlayColor = vec4(overlayColor.w > 0.0 ? overlayColorOpaque.xyz/overlayColor.w : vec3(1.0), overlayColor.w);
  73. vec4 viewPosition = view*vec4(vpos, 1.0);
  74. vec4 waterColorLinear = getOverlayWaterColor(overlayWaterMask, waterOverlayColor, -normalize(vpos - cameraPosition), shadow, vnormal, tbnMatrix, viewPosition.xyz, vpos + localOrigin);
  75. vec4 waterColorNonLinear = delinearizeGamma(vec4(waterColorLinear.xyz, 1.0));
  76. // un-gamma the ground color to mix in linear space
  77. gl_FragColor = mix(groundColor, waterColorNonLinear, waterColorLinear.w);
  78. }`:""}
  79. ${r.screenSizePerspective?U`
  80. float perspectiveScale = screenSizePerspectiveScaleFloat(1.0, screenSizeCosAngle, screenSizeDistanceToCamera, vec4(0.0, 0.0, 0.0, 0.0));
  81. if (perspectiveScale <= 0.25) {
  82. gl_FragColor = mix(gl_FragColor, vec4(1.0, 0.0, 0.0, 1.0), perspectiveScale * 4.0);
  83. }
  84. else if (perspectiveScale <= 0.5) {
  85. gl_FragColor = mix(gl_FragColor, vec4(0.0, 0.0, 1.0, 1.0), (perspectiveScale - 0.25) * 4.0);
  86. }
  87. else if (perspectiveScale >= 0.99) {
  88. gl_FragColor = mix(gl_FragColor, vec4(0.0, 1.0, 0.0, 1.0), 0.2);
  89. }
  90. else {
  91. gl_FragColor = mix(gl_FragColor, vec4(1.0, 0.0, 1.0, 1.0), (perspectiveScale - 0.5) * 2.0);
  92. }`:""}
  93. ${r.visualizeNormals?r.spherical?U`
  94. vec3 localUp = normalize(vpos + localOrigin);
  95. vec3 right = normalize(cross(vec3(0.0,0.0,1.0),localUp));
  96. vec3 forward = normalize(cross(localUp,right));
  97. mat3 tbn = mat3(right, forward, localUp);
  98. vec3 tNormal = normalize(normal* tbn);
  99. gl_FragColor = vec4(vec3(0.5) + 0.5 * tNormal, 0.0);
  100. `:U`
  101. vec3 tNormal = normalize(normal);
  102. gl_FragColor = vec4(vec3(0.5) + 0.5 * tNormal, 0.0);
  103. `:""}
  104. ${r.tileBorders?U`
  105. vec2 dVuv = fwidth(vuv0);
  106. vec2 edgeFactors = smoothstep(vec2(0.0), 1.5 * dVuv, min(vuv0, 1.0 - vuv0));
  107. float edgeFactor = 1.0 - min(edgeFactors.x, edgeFactors.y);
  108. gl_FragColor = mix(gl_FragColor, vec4(1.0, 0.0, 0.0, 1.0), edgeFactor);`:""}
  109. gl_FragColor = highlightSlice(gl_FragColor, vpos);
  110. }
  111. `)}break;case d.Depth:i.include(F,r),i.include(h,r),t(i),n(i),_.code.add(U`
  112. void main(void) {
  113. ${q?U`setOverlayVTC(getUV0());`:""}
  114. gl_Position = transformPositionWithDepth(proj, view, position, nearFar, linearDepth);
  115. }
  116. `),B.code.add(U`
  117. void main() {
  118. ${q?U`
  119. vec4 overlayColor = getCombinedOverlayColor();
  120. ${r.transparent?U`if (overlayColor.a == 0.0) { discard; }`:""}`:""}
  121. outputDepth(linearDepth);
  122. }
  123. `);break;case d.Shadow:case d.ShadowHighlight:case d.ShadowExludeHighlight:i.include(h,r),t(i),n(i),_.code.add(U`void main(void) {
  124. gl_Position = transformPositionWithDepth(proj, view, position, nearFar, linearDepth);
  125. }`),B.code.add(U`void main() {
  126. outputDepth(linearDepth);
  127. }`);break;case d.Normal:E.add("vnormal","vec3"),N(_),I(),_.code.add(U`void main(void) {
  128. vec3 normal = getNormal();
  129. gl_Position = transformPosition(proj, view, position);
  130. vnormal = normalize((viewNormal * vec4(normal, 1.0)).xyz);
  131. }`),B.code.add(U`void main() {
  132. vec3 normal = normalize(vnormal);
  133. if (gl_FrontFacing == false) {
  134. normal = -normal;
  135. }
  136. gl_FragColor = vec4(vec3(0.5) + 0.5 * normal, 0.0);
  137. }`);break;case d.Highlight:i.include(F,r),_.code.add(U`void main() {
  138. setOverlayVTC(getUV0());
  139. gl_Position = transformPosition(proj, view, position);
  140. }`),i.include(u,r),B.code.add(U`void main() {
  141. vec4 overlayColor = getCombinedOverlayColor();
  142. if (overlayColor.a == 0.0) {
  143. discard;
  144. }
  145. outputHighlight();
  146. }`)}return r.output===d.ObjectAndLayerIdColor&&(i.include(F,{...r,pbrMode:j.Disabled}),_.code.add(U`void main(void) {
  147. gl_Position = transformPosition(proj, view, position);
  148. setOverlayVTC(getUV0());
  149. }`),B.code.add(U`
  150. void main() {
  151. vec2 texDim = ${M(r,"ovColorTex")};
  152. gl_FragColor = ${$(r,"ovColorTex","vec2(vtcOverlay.x * 0.5, vtcOverlay.y)*texDim")};
  153. }
  154. `)),i}const G=r(),H=i(),I=Object.freeze(Object.defineProperty({__proto__:null,TerrainPassParameters:B,build:E},Symbol.toStringTag,{value:"Module"}));export{B as T,I as a,E as b};