智慧水务管理系统 - 精河县供水工程综合管理平台

GlobeFS.glsl 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. uniform vec4 u_initialColor;
  2. #if TEXTURE_UNITS > 0
  3. uniform sampler2D u_dayTextures[TEXTURE_UNITS];
  4. uniform vec4 u_dayTextureTranslationAndScale[TEXTURE_UNITS];
  5. uniform bool u_dayTextureUseWebMercatorT[TEXTURE_UNITS];
  6. #ifdef APPLY_ALPHA
  7. uniform float u_dayTextureAlpha[TEXTURE_UNITS];
  8. #endif
  9. #ifdef APPLY_DAY_NIGHT_ALPHA
  10. uniform float u_dayTextureNightAlpha[TEXTURE_UNITS];
  11. uniform float u_dayTextureDayAlpha[TEXTURE_UNITS];
  12. #endif
  13. #ifdef APPLY_SPLIT
  14. uniform float u_dayTextureSplit[TEXTURE_UNITS];
  15. #endif
  16. #ifdef APPLY_BRIGHTNESS
  17. uniform float u_dayTextureBrightness[TEXTURE_UNITS];
  18. #endif
  19. #ifdef APPLY_CONTRAST
  20. uniform float u_dayTextureContrast[TEXTURE_UNITS];
  21. #endif
  22. #ifdef APPLY_HUE
  23. uniform float u_dayTextureHue[TEXTURE_UNITS];
  24. #endif
  25. #ifdef APPLY_SATURATION
  26. uniform float u_dayTextureSaturation[TEXTURE_UNITS];
  27. #endif
  28. #ifdef APPLY_GAMMA
  29. uniform float u_dayTextureOneOverGamma[TEXTURE_UNITS];
  30. #endif
  31. #ifdef APPLY_IMAGERY_CUTOUT
  32. uniform vec4 u_dayTextureCutoutRectangles[TEXTURE_UNITS];
  33. #endif
  34. #ifdef APPLY_COLOR_TO_ALPHA
  35. uniform vec4 u_colorsToAlpha[TEXTURE_UNITS];
  36. #endif
  37. uniform vec4 u_dayTextureTexCoordsRectangle[TEXTURE_UNITS];
  38. #endif
  39. #if defined(HAS_WATER_MASK) && (defined(SHOW_REFLECTIVE_OCEAN) || defined(APPLY_MATERIAL))
  40. uniform sampler2D u_waterMask;
  41. uniform vec4 u_waterMaskTranslationAndScale;
  42. uniform float u_zoomedOutOceanSpecularIntensity;
  43. #endif
  44. #ifdef SHOW_OCEAN_WAVES
  45. uniform sampler2D u_oceanNormalMap;
  46. #endif
  47. #if defined(ENABLE_DAYNIGHT_SHADING) || defined(GROUND_ATMOSPHERE)
  48. uniform vec2 u_lightingFadeDistance;
  49. #endif
  50. #ifdef TILE_LIMIT_RECTANGLE
  51. uniform vec4 u_cartographicLimitRectangle;
  52. #endif
  53. #ifdef GROUND_ATMOSPHERE
  54. uniform vec2 u_nightFadeDistance;
  55. #endif
  56. #ifdef ENABLE_CLIPPING_PLANES
  57. uniform highp sampler2D u_clippingPlanes;
  58. uniform mat4 u_clippingPlanesMatrix;
  59. uniform vec4 u_clippingPlanesEdgeStyle;
  60. #endif
  61. #ifdef ENABLE_CLIPPING_POLYGONS
  62. uniform highp sampler2D u_clippingDistance;
  63. in vec2 v_clippingPosition;
  64. flat in int v_regionIndex;
  65. #endif
  66. #if defined(GROUND_ATMOSPHERE) || defined(FOG) && defined(DYNAMIC_ATMOSPHERE_LIGHTING) && (defined(ENABLE_VERTEX_LIGHTING) || defined(ENABLE_DAYNIGHT_SHADING))
  67. uniform float u_minimumBrightness;
  68. #endif
  69. // Based on colorCorrect
  70. // The colorCorrect flag can only be true when tileProvider.hue/saturation/brightnessShift
  71. // are nonzero AND when (applyFog || showGroundAtmosphere) in the tile provider
  72. // - The tileProvider.hue/saturation/brightnessShift are just passed through
  73. // from the Globe hue/saturation/brightness, like atmosphereBrightnessShift
  74. // - The applyFog depends on enableFog, and some tile distance from the viewer
  75. // - The showGroundAtmosphere is a flag that is passed through from the Globe,
  76. // and is true by default when the ellipsoid is WGS84
  77. #ifdef COLOR_CORRECT
  78. uniform vec3 u_hsbShift; // Hue, saturation, brightness
  79. #endif
  80. // Based on highlightFillTile
  81. // This is set for terrain tiles when they are "fill" tiles, and
  82. // the terrainProvider.fillHighlightColor was set to a value with
  83. // nonzero alpha
  84. #ifdef HIGHLIGHT_FILL_TILE
  85. uniform vec4 u_fillHighlightColor;
  86. #endif
  87. // Based on translucent
  88. // This is set depending on the GlobeTranslucencyState
  89. #ifdef TRANSLUCENT
  90. uniform vec4 u_frontFaceAlphaByDistance;
  91. uniform vec4 u_backFaceAlphaByDistance;
  92. uniform vec4 u_translucencyRectangle;
  93. #endif
  94. // Based on showUndergroundColor
  95. // This is set when GlobeSurfaceTileProvider.isUndergroundVisible
  96. // returns true, AND the tileProvider.undergroundColor had a value with
  97. // nonzero alpha, and the tileProvider.undergroundColorAlphaByDistance
  98. // was in the right range
  99. #ifdef UNDERGROUND_COLOR
  100. uniform vec4 u_undergroundColor;
  101. uniform vec4 u_undergroundColorAlphaByDistance;
  102. #endif
  103. // Based on enableLighting && hasVertexNormals
  104. // The enableLighting flag is passed in directly from the Globe.
  105. // The hasVertexNormals flag is from the tileProvider
  106. #ifdef ENABLE_VERTEX_LIGHTING
  107. uniform float u_lambertDiffuseMultiplier;
  108. uniform float u_vertexShadowDarkness;
  109. #endif
  110. in vec3 v_positionMC;
  111. in vec3 v_positionEC;
  112. in vec3 v_textureCoordinates;
  113. in vec3 v_normalMC;
  114. in vec3 v_normalEC;
  115. #ifdef APPLY_MATERIAL
  116. in float v_height;
  117. in float v_slope;
  118. in float v_aspect;
  119. #endif
  120. #if defined(FOG) || defined(GROUND_ATMOSPHERE) || defined(UNDERGROUND_COLOR) || defined(TRANSLUCENT)
  121. in float v_distance;
  122. #endif
  123. #if defined(GROUND_ATMOSPHERE) || defined(FOG)
  124. in vec3 v_atmosphereRayleighColor;
  125. in vec3 v_atmosphereMieColor;
  126. in float v_atmosphereOpacity;
  127. #endif
  128. #if defined(UNDERGROUND_COLOR) || defined(TRANSLUCENT)
  129. float interpolateByDistance(vec4 nearFarScalar, float distance)
  130. {
  131. float startDistance = nearFarScalar.x;
  132. float startValue = nearFarScalar.y;
  133. float endDistance = nearFarScalar.z;
  134. float endValue = nearFarScalar.w;
  135. float t = clamp((distance - startDistance) / (endDistance - startDistance), 0.0, 1.0);
  136. return mix(startValue, endValue, t);
  137. }
  138. #endif
  139. #if defined(UNDERGROUND_COLOR) || defined(TRANSLUCENT) || defined(APPLY_MATERIAL)
  140. vec4 alphaBlend(vec4 sourceColor, vec4 destinationColor)
  141. {
  142. return sourceColor * vec4(sourceColor.aaa, 1.0) + destinationColor * (1.0 - sourceColor.a);
  143. }
  144. #endif
  145. #ifdef TRANSLUCENT
  146. bool inTranslucencyRectangle()
  147. {
  148. return
  149. v_textureCoordinates.x > u_translucencyRectangle.x &&
  150. v_textureCoordinates.x < u_translucencyRectangle.z &&
  151. v_textureCoordinates.y > u_translucencyRectangle.y &&
  152. v_textureCoordinates.y < u_translucencyRectangle.w;
  153. }
  154. #endif
  155. vec4 sampleAndBlend(
  156. vec4 previousColor,
  157. sampler2D textureToSample,
  158. vec2 tileTextureCoordinates,
  159. vec4 textureCoordinateRectangle,
  160. vec4 textureCoordinateTranslationAndScale,
  161. float textureAlpha,
  162. float textureNightAlpha,
  163. float textureDayAlpha,
  164. float textureBrightness,
  165. float textureContrast,
  166. float textureHue,
  167. float textureSaturation,
  168. float textureOneOverGamma,
  169. float split,
  170. vec4 colorToAlpha,
  171. float nightBlend)
  172. {
  173. // This crazy step stuff sets the alpha to 0.0 if this following condition is true:
  174. // tileTextureCoordinates.s < textureCoordinateRectangle.s ||
  175. // tileTextureCoordinates.s > textureCoordinateRectangle.p ||
  176. // tileTextureCoordinates.t < textureCoordinateRectangle.t ||
  177. // tileTextureCoordinates.t > textureCoordinateRectangle.q
  178. // In other words, the alpha is zero if the fragment is outside the rectangle
  179. // covered by this texture. Would an actual 'if' yield better performance?
  180. vec2 alphaMultiplier = step(textureCoordinateRectangle.st, tileTextureCoordinates);
  181. textureAlpha = textureAlpha * alphaMultiplier.x * alphaMultiplier.y;
  182. alphaMultiplier = step(vec2(0.0), textureCoordinateRectangle.pq - tileTextureCoordinates);
  183. textureAlpha = textureAlpha * alphaMultiplier.x * alphaMultiplier.y;
  184. #if defined(APPLY_DAY_NIGHT_ALPHA) && defined(ENABLE_DAYNIGHT_SHADING)
  185. textureAlpha *= mix(textureDayAlpha, textureNightAlpha, nightBlend);
  186. #endif
  187. vec2 translation = textureCoordinateTranslationAndScale.xy;
  188. vec2 scale = textureCoordinateTranslationAndScale.zw;
  189. vec2 textureCoordinates = tileTextureCoordinates * scale + translation;
  190. vec4 value = texture(textureToSample, textureCoordinates);
  191. vec3 color = value.rgb;
  192. float alpha = value.a;
  193. #ifdef APPLY_COLOR_TO_ALPHA
  194. vec3 colorDiff = abs(color.rgb - colorToAlpha.rgb);
  195. colorDiff.r = czm_maximumComponent(colorDiff);
  196. alpha = czm_branchFreeTernary(colorDiff.r < colorToAlpha.a, 0.0, alpha);
  197. #endif
  198. #if !defined(APPLY_GAMMA)
  199. vec4 tempColor = czm_gammaCorrect(vec4(color, alpha));
  200. color = tempColor.rgb;
  201. alpha = tempColor.a;
  202. #else
  203. color = pow(color, vec3(textureOneOverGamma));
  204. #endif
  205. #ifdef APPLY_SPLIT
  206. float splitPosition = czm_splitPosition;
  207. // Split to the left
  208. if (split < 0.0 && gl_FragCoord.x > splitPosition) {
  209. alpha = 0.0;
  210. }
  211. // Split to the right
  212. else if (split > 0.0 && gl_FragCoord.x < splitPosition) {
  213. alpha = 0.0;
  214. }
  215. #endif
  216. #ifdef APPLY_BRIGHTNESS
  217. color = mix(vec3(0.0), color, textureBrightness);
  218. #endif
  219. #ifdef APPLY_CONTRAST
  220. color = mix(vec3(0.5), color, textureContrast);
  221. #endif
  222. #ifdef APPLY_HUE
  223. color = czm_hue(color, textureHue);
  224. #endif
  225. #ifdef APPLY_SATURATION
  226. color = czm_saturation(color, textureSaturation);
  227. #endif
  228. float sourceAlpha = alpha * textureAlpha;
  229. float outAlpha = mix(previousColor.a, 1.0, sourceAlpha);
  230. outAlpha += sign(outAlpha) - 1.0;
  231. vec3 outColor = mix(previousColor.rgb * previousColor.a, color, sourceAlpha) / outAlpha;
  232. // When rendering imagery for a tile in multiple passes,
  233. // some GPU/WebGL implementation combinations will not blend fragments in
  234. // additional passes correctly if their computation includes an unmasked
  235. // divide-by-zero operation,
  236. // even if it's not in the output or if the output has alpha zero.
  237. //
  238. // For example, without sanitization for outAlpha,
  239. // this renders without artifacts:
  240. // if (outAlpha == 0.0) { outColor = vec3(0.0); }
  241. //
  242. // but using czm_branchFreeTernary will cause portions of the tile that are
  243. // alpha-zero in the additional pass to render as black instead of blending
  244. // with the previous pass:
  245. // outColor = czm_branchFreeTernary(outAlpha == 0.0, vec3(0.0), outColor);
  246. //
  247. // So instead, sanitize against divide-by-zero,
  248. // store this state on the sign of outAlpha, and correct on return.
  249. return vec4(outColor, max(outAlpha, 0.0));
  250. }
  251. vec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates, float nightBlend);
  252. vec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat3 enuToEye, vec4 imageryColor, float specularMapValue, float fade);
  253. const float fExposure = 2.0;
  254. vec3 computeEllipsoidPosition()
  255. {
  256. float mpp = czm_metersPerPixel(vec4(0.0, 0.0, -czm_currentFrustum.x, 1.0), 1.0);
  257. vec2 xy = gl_FragCoord.xy / czm_viewport.zw * 2.0 - vec2(1.0);
  258. xy *= czm_viewport.zw * mpp * 0.5;
  259. vec3 direction;
  260. if (czm_orthographicIn3D == 1.0)
  261. {
  262. direction = vec3(0.0, 0.0, -1.0);
  263. }
  264. else
  265. {
  266. direction = normalize(vec3(xy, -czm_currentFrustum.x));
  267. }
  268. czm_ray ray = czm_ray(vec3(0.0), direction);
  269. vec3 ellipsoid_center = czm_view[3].xyz;
  270. czm_raySegment intersection = czm_rayEllipsoidIntersectionInterval(ray, ellipsoid_center, czm_ellipsoidInverseRadii);
  271. vec3 ellipsoidPosition = czm_pointAlongRay(ray, intersection.start);
  272. return (czm_inverseView * vec4(ellipsoidPosition, 1.0)).xyz;
  273. }
  274. void main()
  275. {
  276. #ifdef TILE_LIMIT_RECTANGLE
  277. if (v_textureCoordinates.x < u_cartographicLimitRectangle.x || u_cartographicLimitRectangle.z < v_textureCoordinates.x ||
  278. v_textureCoordinates.y < u_cartographicLimitRectangle.y || u_cartographicLimitRectangle.w < v_textureCoordinates.y)
  279. {
  280. discard;
  281. }
  282. #endif
  283. #ifdef ENABLE_CLIPPING_PLANES
  284. float clipDistance = clip(gl_FragCoord, u_clippingPlanes, u_clippingPlanesMatrix);
  285. #endif
  286. #if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) || defined(HDR)
  287. vec3 normalMC = czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)); // normalized surface normal in model coordinates
  288. vec3 normalEC = czm_normal3D * normalMC; // normalized surface normal in eye coordinates
  289. #endif
  290. #if defined(APPLY_DAY_NIGHT_ALPHA) && defined(ENABLE_DAYNIGHT_SHADING)
  291. float nightBlend = 1.0 - clamp(czm_getLambertDiffuse(czm_lightDirectionEC, normalEC) * 5.0, 0.0, 1.0);
  292. #else
  293. float nightBlend = 0.0;
  294. #endif
  295. // The clamp below works around an apparent bug in Chrome Canary v23.0.1241.0
  296. // where the fragment shader sees textures coordinates < 0.0 and > 1.0 for the
  297. // fragments on the edges of tiles even though the vertex shader is outputting
  298. // coordinates strictly in the 0-1 range.
  299. vec4 color = computeDayColor(u_initialColor, clamp(v_textureCoordinates, 0.0, 1.0), nightBlend);
  300. #ifdef SHOW_TILE_BOUNDARIES
  301. if (v_textureCoordinates.x < (1.0/256.0) || v_textureCoordinates.x > (255.0/256.0) ||
  302. v_textureCoordinates.y < (1.0/256.0) || v_textureCoordinates.y > (255.0/256.0))
  303. {
  304. color = vec4(1.0, 0.0, 0.0, 1.0);
  305. }
  306. #endif
  307. #if defined(ENABLE_DAYNIGHT_SHADING) || defined(GROUND_ATMOSPHERE)
  308. float cameraDist;
  309. if (czm_sceneMode == czm_sceneMode2D)
  310. {
  311. cameraDist = max(czm_frustumPlanes.x - czm_frustumPlanes.y, czm_frustumPlanes.w - czm_frustumPlanes.z) * 0.5;
  312. }
  313. else if (czm_sceneMode == czm_sceneModeColumbusView)
  314. {
  315. cameraDist = -czm_view[3].z;
  316. }
  317. else
  318. {
  319. cameraDist = length(czm_view[3]);
  320. }
  321. float fadeOutDist = u_lightingFadeDistance.x;
  322. float fadeInDist = u_lightingFadeDistance.y;
  323. if (czm_sceneMode != czm_sceneMode3D) {
  324. vec3 radii = czm_ellipsoidRadii;
  325. float maxRadii = max(radii.x, max(radii.y, radii.z));
  326. fadeOutDist -= maxRadii;
  327. fadeInDist -= maxRadii;
  328. }
  329. float fade = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.0, 1.0);
  330. #else
  331. float fade = 0.0;
  332. #endif
  333. #if defined(HAS_WATER_MASK) && (defined(SHOW_REFLECTIVE_OCEAN) || defined(APPLY_MATERIAL))
  334. vec2 waterMaskTranslation = u_waterMaskTranslationAndScale.xy;
  335. vec2 waterMaskScale = u_waterMaskTranslationAndScale.zw;
  336. vec2 waterMaskTextureCoordinates = v_textureCoordinates.xy * waterMaskScale + waterMaskTranslation;
  337. waterMaskTextureCoordinates.y = 1.0 - waterMaskTextureCoordinates.y;
  338. float mask = texture(u_waterMask, waterMaskTextureCoordinates).r;
  339. #ifdef SHOW_REFLECTIVE_OCEAN
  340. if (mask > 0.0)
  341. {
  342. mat3 enuToEye = czm_eastNorthUpToEyeCoordinates(v_positionMC, normalEC);
  343. vec2 ellipsoidTextureCoordinates = czm_ellipsoidTextureCoordinates(normalMC);
  344. vec2 ellipsoidFlippedTextureCoordinates = czm_ellipsoidTextureCoordinates(normalMC.zyx);
  345. vec2 textureCoordinates = mix(ellipsoidTextureCoordinates, ellipsoidFlippedTextureCoordinates, czm_morphTime * smoothstep(0.9, 0.95, normalMC.z));
  346. color = computeWaterColor(v_positionEC, textureCoordinates, enuToEye, color, mask, fade);
  347. }
  348. #endif
  349. #endif
  350. #ifdef APPLY_MATERIAL
  351. czm_materialInput materialInput;
  352. materialInput.st = v_textureCoordinates.st;
  353. materialInput.normalEC = normalize(v_normalEC);
  354. materialInput.positionToEyeEC = -v_positionEC;
  355. materialInput.tangentToEyeMatrix = czm_eastNorthUpToEyeCoordinates(v_positionMC, normalize(v_normalEC));
  356. materialInput.slope = v_slope;
  357. materialInput.height = v_height;
  358. materialInput.aspect = v_aspect;
  359. #ifdef HAS_WATER_MASK
  360. materialInput.waterMask = mask;
  361. #endif
  362. czm_material material = czm_getMaterial(materialInput);
  363. vec4 materialColor = vec4(material.diffuse, material.alpha);
  364. color = alphaBlend(materialColor, color);
  365. #endif
  366. #ifdef ENABLE_VERTEX_LIGHTING
  367. float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_lightDirectionEC, normalize(v_normalEC)) * u_lambertDiffuseMultiplier + u_vertexShadowDarkness, 0.0, 1.0);
  368. vec4 finalColor = vec4(color.rgb * czm_lightColor * diffuseIntensity, color.a);
  369. #elif defined(ENABLE_DAYNIGHT_SHADING)
  370. float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_lightDirectionEC, normalEC) * 5.0 + 0.3, 0.0, 1.0);
  371. diffuseIntensity = mix(1.0, diffuseIntensity, fade);
  372. vec4 finalColor = vec4(color.rgb * czm_lightColor * diffuseIntensity, color.a);
  373. #else
  374. vec4 finalColor = color;
  375. #endif
  376. #ifdef ENABLE_CLIPPING_PLANES
  377. vec4 clippingPlanesEdgeColor = vec4(1.0);
  378. clippingPlanesEdgeColor.rgb = u_clippingPlanesEdgeStyle.rgb;
  379. float clippingPlanesEdgeWidth = u_clippingPlanesEdgeStyle.a;
  380. if (clipDistance < clippingPlanesEdgeWidth)
  381. {
  382. finalColor = clippingPlanesEdgeColor;
  383. }
  384. #endif
  385. #ifdef ENABLE_CLIPPING_POLYGONS
  386. vec2 clippingPosition = v_clippingPosition;
  387. int regionIndex = v_regionIndex;
  388. clipPolygons(u_clippingDistance, CLIPPING_POLYGON_REGIONS_LENGTH, clippingPosition, regionIndex);
  389. #endif
  390. #ifdef HIGHLIGHT_FILL_TILE
  391. finalColor = vec4(mix(finalColor.rgb, u_fillHighlightColor.rgb, u_fillHighlightColor.a), finalColor.a);
  392. #endif
  393. #if defined(DYNAMIC_ATMOSPHERE_LIGHTING_FROM_SUN)
  394. vec3 atmosphereLightDirection = czm_sunDirectionWC;
  395. #else
  396. vec3 atmosphereLightDirection = czm_lightDirectionWC;
  397. #endif
  398. #if defined(GROUND_ATMOSPHERE) || defined(FOG)
  399. if (!czm_backFacing())
  400. {
  401. bool dynamicLighting = false;
  402. #if defined(DYNAMIC_ATMOSPHERE_LIGHTING) && (defined(ENABLE_DAYNIGHT_SHADING) || defined(ENABLE_VERTEX_LIGHTING))
  403. dynamicLighting = true;
  404. #endif
  405. vec3 rayleighColor;
  406. vec3 mieColor;
  407. float opacity;
  408. vec3 positionWC;
  409. vec3 lightDirection;
  410. // When the camera is far away (camera distance > nightFadeOutDistance), the scattering is computed in the fragment shader.
  411. // Otherwise, the scattering is computed in the vertex shader.
  412. #ifdef PER_FRAGMENT_GROUND_ATMOSPHERE
  413. positionWC = computeEllipsoidPosition();
  414. lightDirection = czm_branchFreeTernary(dynamicLighting, atmosphereLightDirection, normalize(positionWC));
  415. computeAtmosphereScattering(
  416. positionWC,
  417. lightDirection,
  418. rayleighColor,
  419. mieColor,
  420. opacity
  421. );
  422. #else
  423. positionWC = v_positionMC;
  424. lightDirection = czm_branchFreeTernary(dynamicLighting, atmosphereLightDirection, normalize(positionWC));
  425. rayleighColor = v_atmosphereRayleighColor;
  426. mieColor = v_atmosphereMieColor;
  427. opacity = v_atmosphereOpacity;
  428. #endif
  429. #ifdef COLOR_CORRECT
  430. const bool ignoreBlackPixels = true;
  431. rayleighColor = czm_applyHSBShift(rayleighColor, u_hsbShift, ignoreBlackPixels);
  432. mieColor = czm_applyHSBShift(mieColor, u_hsbShift, ignoreBlackPixels);
  433. #endif
  434. vec4 groundAtmosphereColor = computeAtmosphereColor(positionWC, lightDirection, rayleighColor, mieColor, opacity);
  435. // Fog is applied to tiles selected for fog, close to the Earth.
  436. #ifdef FOG
  437. vec3 fogColor = groundAtmosphereColor.rgb;
  438. // If there is lighting, apply that to the fog.
  439. #if defined(DYNAMIC_ATMOSPHERE_LIGHTING) && (defined(ENABLE_VERTEX_LIGHTING) || defined(ENABLE_DAYNIGHT_SHADING))
  440. float darken = clamp(dot(normalize(czm_viewerPositionWC), atmosphereLightDirection), u_minimumBrightness, 1.0);
  441. fogColor *= darken;
  442. #endif
  443. #ifndef HDR
  444. fogColor.rgb = czm_pbrNeutralTonemapping(fogColor.rgb);
  445. fogColor.rgb = czm_inverseGamma(fogColor.rgb);
  446. #endif
  447. finalColor = vec4(czm_fog(v_distance, finalColor.rgb, fogColor.rgb, czm_fogVisualDensityScalar), finalColor.a);
  448. #else
  449. // Apply ground atmosphere. This happens when the camera is far away from the earth.
  450. // The transmittance is based on optical depth i.e. the length of segment of the ray inside the atmosphere.
  451. // This value is larger near the "circumference", as it is further away from the camera. We use it to
  452. // brighten up that area of the ground atmosphere.
  453. const float transmittanceModifier = 0.5;
  454. float transmittance = transmittanceModifier + clamp(1.0 - groundAtmosphereColor.a, 0.0, 1.0);
  455. vec3 finalAtmosphereColor = finalColor.rgb + groundAtmosphereColor.rgb * transmittance;
  456. #if defined(DYNAMIC_ATMOSPHERE_LIGHTING) && (defined(ENABLE_VERTEX_LIGHTING) || defined(ENABLE_DAYNIGHT_SHADING))
  457. float fadeInDist = u_nightFadeDistance.x;
  458. float fadeOutDist = u_nightFadeDistance.y;
  459. float sunlitAtmosphereIntensity = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.05, 1.0);
  460. float darken = clamp(dot(normalize(positionWC), atmosphereLightDirection), 0.0, 1.0);
  461. vec3 darkenendGroundAtmosphereColor = mix(groundAtmosphereColor.rgb, finalAtmosphereColor.rgb, darken);
  462. finalAtmosphereColor = mix(darkenendGroundAtmosphereColor, finalAtmosphereColor, sunlitAtmosphereIntensity);
  463. #endif
  464. #ifndef HDR
  465. finalAtmosphereColor.rgb = vec3(1.0) - exp(-fExposure * finalAtmosphereColor.rgb);
  466. #else
  467. finalAtmosphereColor.rgb = czm_saturation(finalAtmosphereColor.rgb, 1.6);
  468. #endif
  469. finalColor.rgb = mix(finalColor.rgb, finalAtmosphereColor.rgb, fade);
  470. #endif
  471. }
  472. #endif
  473. #ifdef UNDERGROUND_COLOR
  474. if (czm_backFacing())
  475. {
  476. float distanceFromEllipsoid = max(czm_eyeHeight, 0.0);
  477. float distance = max(v_distance - distanceFromEllipsoid, 0.0);
  478. float blendAmount = interpolateByDistance(u_undergroundColorAlphaByDistance, distance);
  479. vec4 undergroundColor = vec4(u_undergroundColor.rgb, u_undergroundColor.a * blendAmount);
  480. finalColor = alphaBlend(undergroundColor, finalColor);
  481. }
  482. #endif
  483. #ifdef TRANSLUCENT
  484. if (inTranslucencyRectangle())
  485. {
  486. vec4 alphaByDistance = gl_FrontFacing ? u_frontFaceAlphaByDistance : u_backFaceAlphaByDistance;
  487. finalColor.a *= interpolateByDistance(alphaByDistance, v_distance);
  488. }
  489. #endif
  490. out_FragColor = finalColor;
  491. }
  492. #ifdef SHOW_REFLECTIVE_OCEAN
  493. float waveFade(float edge0, float edge1, float x)
  494. {
  495. float y = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
  496. return pow(1.0 - y, 5.0);
  497. }
  498. float linearFade(float edge0, float edge1, float x)
  499. {
  500. return clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
  501. }
  502. // Based on water rendering by Jonas Wagner:
  503. // http://29a.ch/2012/7/19/webgl-terrain-rendering-water-fog
  504. // low altitude wave settings
  505. const float oceanFrequencyLowAltitude = 825000.0;
  506. const float oceanAnimationSpeedLowAltitude = 0.004;
  507. const float oceanOneOverAmplitudeLowAltitude = 1.0 / 2.0;
  508. const float oceanSpecularIntensity = 0.5;
  509. // high altitude wave settings
  510. const float oceanFrequencyHighAltitude = 125000.0;
  511. const float oceanAnimationSpeedHighAltitude = 0.008;
  512. const float oceanOneOverAmplitudeHighAltitude = 1.0 / 2.0;
  513. vec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat3 enuToEye, vec4 imageryColor, float maskValue, float fade)
  514. {
  515. vec3 positionToEyeEC = -positionEyeCoordinates;
  516. float positionToEyeECLength = length(positionToEyeEC);
  517. // The double normalize below works around a bug in Firefox on Android devices.
  518. vec3 normalizedPositionToEyeEC = normalize(normalize(positionToEyeEC));
  519. // Fade out the waves as the camera moves far from the surface.
  520. float waveIntensity = waveFade(70000.0, 1000000.0, positionToEyeECLength);
  521. #ifdef SHOW_OCEAN_WAVES
  522. // high altitude waves
  523. float time = czm_frameNumber * oceanAnimationSpeedHighAltitude;
  524. vec4 noise = czm_getWaterNoise(u_oceanNormalMap, textureCoordinates * oceanFrequencyHighAltitude, time, 0.0);
  525. vec3 normalTangentSpaceHighAltitude = vec3(noise.xy, noise.z * oceanOneOverAmplitudeHighAltitude);
  526. // low altitude waves
  527. time = czm_frameNumber * oceanAnimationSpeedLowAltitude;
  528. noise = czm_getWaterNoise(u_oceanNormalMap, textureCoordinates * oceanFrequencyLowAltitude, time, 0.0);
  529. vec3 normalTangentSpaceLowAltitude = vec3(noise.xy, noise.z * oceanOneOverAmplitudeLowAltitude);
  530. // blend the 2 wave layers based on distance to surface
  531. float highAltitudeFade = linearFade(0.0, 60000.0, positionToEyeECLength);
  532. float lowAltitudeFade = 1.0 - linearFade(20000.0, 60000.0, positionToEyeECLength);
  533. vec3 normalTangentSpace =
  534. (highAltitudeFade * normalTangentSpaceHighAltitude) +
  535. (lowAltitudeFade * normalTangentSpaceLowAltitude);
  536. normalTangentSpace = normalize(normalTangentSpace);
  537. // fade out the normal perturbation as we move farther from the water surface
  538. normalTangentSpace.xy *= waveIntensity;
  539. normalTangentSpace = normalize(normalTangentSpace);
  540. #else
  541. vec3 normalTangentSpace = vec3(0.0, 0.0, 1.0);
  542. #endif
  543. vec3 normalEC = enuToEye * normalTangentSpace;
  544. const vec3 waveHighlightColor = vec3(0.3, 0.45, 0.6);
  545. // Use diffuse light to highlight the waves
  546. float diffuseIntensity = czm_getLambertDiffuse(czm_lightDirectionEC, normalEC) * maskValue;
  547. vec3 diffuseHighlight = waveHighlightColor * diffuseIntensity * (1.0 - fade);
  548. #ifdef SHOW_OCEAN_WAVES
  549. // Where diffuse light is low or non-existent, use wave highlights based solely on
  550. // the wave bumpiness and no particular light direction.
  551. float tsPerturbationRatio = normalTangentSpace.z;
  552. vec3 nonDiffuseHighlight = mix(waveHighlightColor * 5.0 * (1.0 - tsPerturbationRatio), vec3(0.0), diffuseIntensity);
  553. #else
  554. vec3 nonDiffuseHighlight = vec3(0.0);
  555. #endif
  556. // Add specular highlights in 3D, and in all modes when zoomed in.
  557. float specularIntensity = czm_getSpecular(czm_lightDirectionEC, normalizedPositionToEyeEC, normalEC, 10.0);
  558. float surfaceReflectance = mix(0.0, mix(u_zoomedOutOceanSpecularIntensity, oceanSpecularIntensity, waveIntensity), maskValue);
  559. float specular = specularIntensity * surfaceReflectance;
  560. #ifdef HDR
  561. specular *= 1.4;
  562. float e = 0.2;
  563. float d = 3.3;
  564. float c = 1.7;
  565. vec3 color = imageryColor.rgb + (c * (vec3(e) + imageryColor.rgb * d) * (diffuseHighlight + nonDiffuseHighlight + specular));
  566. #else
  567. vec3 color = imageryColor.rgb + diffuseHighlight + nonDiffuseHighlight + specular;
  568. #endif
  569. return vec4(color, imageryColor.a);
  570. }
  571. #endif // #ifdef SHOW_REFLECTIVE_OCEAN