GlobeFS.glsl 23 KB

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