diff --git a/Apps/Sandcastle/gallery/Atmosphere.html b/Apps/Sandcastle/gallery/Atmosphere.html new file mode 100644 index 000000000000..d84f7ce6455e --- /dev/null +++ b/Apps/Sandcastle/gallery/Atmosphere.html @@ -0,0 +1,174 @@ + + +
+ + + + + +Lighting Fade Out Distance | ++ + + | +
Lighting Fade In Distance | ++ + + | +
Night Fade Out Distance | ++ + + | +
Night Fade In Distance | ++ + + | +
enableLighting
is true
.
*
* @type {Number}
- * @default 6500000.0
+ * @default 10000000.0
*/
- this.lightingFadeOutDistance = 6500000.0;
+ this.lightingFadeOutDistance = 1.0e7;
/**
* The distance where lighting resumes. This only takes effect
* when enableLighting
is true
.
*
* @type {Number}
- * @default 9000000.0
+ * @default 20000000.0
+ */
+ this.lightingFadeInDistance = 2.0e7;
+
+ /**
+ * The distance where the darkness of night from the ground atmosphere fades out to a lit ground atmosphere.
+ * This only takes effect when showGroundAtmosphere
and enableLighting
are true
.
+ *
+ * @type {Number}
+ * @default 10000000.0
+ */
+ this.nightFadeOutDistance = 1.0e7;
+
+ /**
+ * The distance where the darkness of night from the ground atmosphere fades in to an unlit ground atmosphere.
+ * This only takes effect when showGroundAtmosphere
and enableLighting
are true
.
+ *
+ * @type {Number}
+ * @default 50000000.0
*/
- this.lightingFadeInDistance = 9000000.0;
+ this.nightFadeInDistance = 5.0e7;
/**
* True if an animated wave effect should be shown in areas of the globe
@@ -187,7 +213,7 @@ define([
this.shadows = ShadowMode.RECEIVE_ONLY;
this._oceanNormalMap = undefined;
- this._zoomedOutOceanSpecularIntensity = 0.5;
+ this._zoomedOutOceanSpecularIntensity = undefined;
}
defineProperties(Globe.prototype, {
@@ -372,7 +398,7 @@ define([
var requireNormals = defined(globe._material) && (globe._material.shaderSource.match(/slope/) || globe._material.shaderSource.match('normalEC'));
- var fragmentSources = [];
+ var fragmentSources = [GroundAtmosphere];
if (defined(globe._material) && (!requireNormals || globe._terrainProvider.requestVertexNormals)) {
fragmentSources.push(globe._material.shaderSource);
defines.push('APPLY_MATERIAL');
@@ -640,11 +666,10 @@ define([
var mode = frameState.mode;
if (pass.render) {
- // Don't show the ocean specular highlights when zoomed out in 2D and Columbus View.
- if (mode === SceneMode.SCENE3D) {
- this._zoomedOutOceanSpecularIntensity = 0.5;
+ if (this.showGroundAtmosphere) {
+ this._zoomedOutOceanSpecularIntensity = 0.4;
} else {
- this._zoomedOutOceanSpecularIntensity = 0.0;
+ this._zoomedOutOceanSpecularIntensity = 0.5;
}
surface.maximumScreenSpaceError = this.maximumScreenSpaceError;
@@ -653,10 +678,13 @@ define([
tileProvider.terrainProvider = this.terrainProvider;
tileProvider.lightingFadeOutDistance = this.lightingFadeOutDistance;
tileProvider.lightingFadeInDistance = this.lightingFadeInDistance;
- tileProvider.zoomedOutOceanSpecularIntensity = this._zoomedOutOceanSpecularIntensity;
+ tileProvider.nightFadeOutDistance = this.nightFadeOutDistance;
+ tileProvider.nightFadeInDistance = this.nightFadeInDistance;
+ tileProvider.zoomedOutOceanSpecularIntensity = mode === SceneMode.SCENE3D ? this._zoomedOutOceanSpecularIntensity : 0.0;
tileProvider.hasWaterMask = hasWaterMask;
tileProvider.oceanNormalMap = this._oceanNormalMap;
tileProvider.enableLighting = this.enableLighting;
+ tileProvider.showGroundAtmosphere = this.showGroundAtmosphere;
tileProvider.shadows = this.shadows;
surface.beginFrame(frameState);
diff --git a/Source/Scene/GlobeSurfaceShaderSet.js b/Source/Scene/GlobeSurfaceShaderSet.js
index 2a8b5b24df08..158106712f56 100644
--- a/Source/Scene/GlobeSurfaceShaderSet.js
+++ b/Source/Scene/GlobeSurfaceShaderSet.js
@@ -66,7 +66,29 @@ define([
return useWebMercatorProjection ? get2DYPositionFractionMercatorProjection : get2DYPositionFractionGeographicProjection;
}
- GlobeSurfaceShaderSet.prototype.getShaderProgram = function(frameState, surfaceTile, numberOfDayTextures, applyBrightness, applyContrast, applyHue, applySaturation, applyGamma, applyAlpha, applySplit, showReflectiveOcean, showOceanWaves, enableLighting, hasVertexNormals, useWebMercatorProjection, enableFog, enableClippingPlanes, clippingPlanes, clippedByBoundaries) {
+ GlobeSurfaceShaderSet.prototype.getShaderProgram = function(options) {
+ var frameState = options.frameState;
+ var surfaceTile = options.surfaceTile;
+ var numberOfDayTextures = options.numberOfDayTextures;
+ var applyBrightness = options.applyBrightness;
+ var applyContrast = options.applyContrast;
+ var applyHue = options.applyHue;
+ var applySaturation = options.applySaturation;
+ var applyGamma = options.applyGamma;
+ var applyAlpha = options.applyAlpha;
+ var applySplit = options.applySplit;
+ var showReflectiveOcean = options.showReflectiveOcean;
+ var showOceanWaves = options.showOceanWaves;
+ var enableLighting = options.enableLighting;
+ var showGroundAtmosphere = options.showGroundAtmosphere;
+ var perFragmentGroundAtmosphere = options.perFragmentGroundAtmosphere;
+ var hasVertexNormals = options.hasVertexNormals;
+ var useWebMercatorProjection = options.useWebMercatorProjection;
+ var enableFog = options.enableFog;
+ var enableClippingPlanes = options.enableClippingPlanes;
+ var clippingPlanes = options.clippingPlanes;
+ var clippedByBoundaries = options.clippedByBoundaries;
+
var quantization = 0;
var quantizationDefine = '';
@@ -102,14 +124,16 @@ define([
(showReflectiveOcean << 8) |
(showOceanWaves << 9) |
(enableLighting << 10) |
- (hasVertexNormals << 11) |
- (useWebMercatorProjection << 12) |
- (enableFog << 13) |
- (quantization << 14) |
- (applySplit << 15) |
- (enableClippingPlanes << 16) |
- (vertexLogDepth << 17) |
- (cartographicLimitRectangleFlag << 18);
+ (showGroundAtmosphere << 11) |
+ (perFragmentGroundAtmosphere << 12) |
+ (hasVertexNormals << 13) |
+ (useWebMercatorProjection << 14) |
+ (enableFog << 15) |
+ (quantization << 16) |
+ (applySplit << 17) |
+ (enableClippingPlanes << 18) |
+ (vertexLogDepth << 19) |
+ (cartographicLimitRectangleFlag << 20);
var currentClippingShaderState = 0;
if (defined(clippingPlanes)) {
@@ -180,6 +204,14 @@ define([
}
}
+ if (showGroundAtmosphere) {
+ vs.defines.push('GROUND_ATMOSPHERE');
+ fs.defines.push('GROUND_ATMOSPHERE');
+ if (perFragmentGroundAtmosphere) {
+ fs.defines.push('PER_FRAGMENT_GROUND_ATMOSPHERE');
+ }
+ }
+
vs.defines.push('INCLUDE_WEB_MERCATOR_Y');
fs.defines.push('INCLUDE_WEB_MERCATOR_Y');
diff --git a/Source/Scene/GlobeSurfaceTileProvider.js b/Source/Scene/GlobeSurfaceTileProvider.js
index 6823dd8bd2e6..b1156145831b 100644
--- a/Source/Scene/GlobeSurfaceTileProvider.js
+++ b/Source/Scene/GlobeSurfaceTileProvider.js
@@ -127,6 +127,7 @@ define([
this.oceanNormalMap = undefined;
this.zoomedOutOceanSpecularIntensity = 0.5;
this.enableLighting = false;
+ this.showGroundAtmosphere = false;
this.shadows = ShadowMode.RECEIVE_ONLY;
this._quadtree = undefined;
@@ -877,6 +878,9 @@ define([
u_lightingFadeDistance : function() {
return this.properties.lightingFadeDistance;
},
+ u_nightFadeDistance : function() {
+ return this.properties.nightFadeDistance;
+ },
u_center3D : function() {
return this.properties.center3D;
},
@@ -982,6 +986,7 @@ define([
zoomedOutOceanSpecularIntensity : 0.5,
oceanNormalMap : undefined,
lightingFadeDistance : new Cartesian2(6500000.0, 9000000.0),
+ nightFadeDistance : new Cartesian2(10000000.0, 40000000.0),
center3D : undefined,
rtc : new Cartesian3(),
@@ -1135,6 +1140,29 @@ define([
})();
var otherPassesInitialColor = new Cartesian4(0.0, 0.0, 0.0, 0.0);
+ var surfaceShaderSetOptionsScratch = {
+ frameState : undefined,
+ surfaceTile : undefined,
+ numberOfDayTextures : undefined,
+ applyBrightness : undefined,
+ applyContrast : undefined,
+ applyHue : undefined,
+ applySaturation : undefined,
+ applyGamma : undefined,
+ applyAlpha : undefined,
+ applySplit : undefined,
+ showReflectiveOcean : undefined,
+ showOceanWaves : undefined,
+ enableLighting : undefined,
+ showGroundAtmosphere : undefined,
+ perFragmentGroundAtmosphere : undefined,
+ hasVertexNormals : undefined,
+ useWebMercatorProjection : undefined,
+ enableFog : undefined,
+ enableClippingPlanes : undefined,
+ clippingPlanes : undefined,
+ clippedByBoundaries : undefined
+ };
function addDrawCommandsForTile(tileProvider, tile, frameState) {
var surfaceTile = tile.data;
@@ -1157,9 +1185,27 @@ define([
var showOceanWaves = showReflectiveOcean && defined(oceanNormalMap);
var hasVertexNormals = tileProvider.terrainProvider.ready && tileProvider.terrainProvider.hasVertexNormals;
var enableFog = frameState.fog.enabled;
+ var showGroundAtmosphere = tileProvider.showGroundAtmosphere;
var castShadows = ShadowMode.castShadows(tileProvider.shadows);
var receiveShadows = ShadowMode.receiveShadows(tileProvider.shadows);
+ var perFragmentGroundAtmosphere = false;
+ if (showGroundAtmosphere) {
+ var mode = frameState.mode;
+ var camera = frameState.camera;
+ var cameraDistance;
+ if (mode === SceneMode.SCENE2D || mode === SceneMode.COLUMBUS_VIEW) {
+ cameraDistance = camera.positionCartographic.height;
+ } else {
+ cameraDistance = Cartesian3.magnitude(camera.positionWC);
+ }
+ var fadeOutDistance = tileProvider.nightFadeOutDistance;
+ if (mode !== SceneMode.SCENE3D) {
+ fadeOutDistance -= frameState.mapProjection.ellipsoid.maximumRadius;
+ }
+ perFragmentGroundAtmosphere = cameraDistance > fadeOutDistance;
+ }
+
if (showReflectiveOcean) {
--maxTextures;
}
@@ -1229,6 +1275,18 @@ define([
}
}
+ var surfaceShaderSetOptions = surfaceShaderSetOptionsScratch;
+ surfaceShaderSetOptions.frameState = frameState;
+ surfaceShaderSetOptions.surfaceTile = surfaceTile;
+ surfaceShaderSetOptions.showReflectiveOcean = showReflectiveOcean;
+ surfaceShaderSetOptions.showOceanWaves = showOceanWaves;
+ surfaceShaderSetOptions.enableLighting = tileProvider.enableLighting;
+ surfaceShaderSetOptions.showGroundAtmosphere = showGroundAtmosphere;
+ surfaceShaderSetOptions.perFragmentGroundAtmosphere = perFragmentGroundAtmosphere;
+ surfaceShaderSetOptions.hasVertexNormals = hasVertexNormals;
+ surfaceShaderSetOptions.useWebMercatorProjection = useWebMercatorProjection;
+ surfaceShaderSetOptions.clippedByBoundaries = surfaceTile.clippedByBoundaries;
+
var tileImageryCollection = surfaceTile.imagery;
var imageryIndex = 0;
var imageryLen = tileImageryCollection.length;
@@ -1287,6 +1345,8 @@ define([
uniformMapProperties.oceanNormalMap = oceanNormalMap;
uniformMapProperties.lightingFadeDistance.x = tileProvider.lightingFadeOutDistance;
uniformMapProperties.lightingFadeDistance.y = tileProvider.lightingFadeInDistance;
+ uniformMapProperties.nightFadeDistance.x = tileProvider.nightFadeOutDistance;
+ uniformMapProperties.nightFadeDistance.y = tileProvider.nightFadeInDistance;
uniformMapProperties.zoomedOutOceanSpecularIntensity = tileProvider.zoomedOutOceanSpecularIntensity;
uniformMapProperties.center3D = surfaceTile.center;
@@ -1414,7 +1474,19 @@ define([
uniformMap = combine(uniformMap, tileProvider.uniformMap);
}
- command.shaderProgram = tileProvider._surfaceShaderSet.getShaderProgram(frameState, surfaceTile, numberOfDayTextures, applyBrightness, applyContrast, applyHue, applySaturation, applyGamma, applyAlpha, applySplit, showReflectiveOcean, showOceanWaves, tileProvider.enableLighting, hasVertexNormals, useWebMercatorProjection, applyFog, clippingPlanesEnabled, clippingPlanes, surfaceTile.clippedByBoundaries);
+ surfaceShaderSetOptions.numberOfDayTextures = numberOfDayTextures;
+ surfaceShaderSetOptions.applyBrightness = applyBrightness;
+ surfaceShaderSetOptions.applyContrast = applyContrast;
+ surfaceShaderSetOptions.applyHue = applyHue;
+ surfaceShaderSetOptions.applySaturation = applySaturation;
+ surfaceShaderSetOptions.applyGamma = applyGamma;
+ surfaceShaderSetOptions.applyAlpha = applyAlpha;
+ surfaceShaderSetOptions.applySplit = applySplit;
+ surfaceShaderSetOptions.enableFog = applyFog;
+ surfaceShaderSetOptions.enableClippingPlanes = clippingPlanesEnabled;
+ surfaceShaderSetOptions.clippingPlanes = clippingPlanes;
+
+ command.shaderProgram = tileProvider._surfaceShaderSet.getShaderProgram(surfaceShaderSetOptions);
command.castShadows = castShadows;
command.receiveShadows = receiveShadows;
command.renderState = renderState;
diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl
index fcae7dcb54c5..980b44484a8b 100644
--- a/Source/Shaders/GlobeFS.glsl
+++ b/Source/Shaders/GlobeFS.glsl
@@ -1,4 +1,3 @@
-//#define SHOW_TILE_BOUNDARIES
uniform vec4 u_initialColor;
#if TEXTURE_UNITS > 0
@@ -47,7 +46,7 @@ uniform float u_zoomedOutOceanSpecularIntensity;
uniform sampler2D u_oceanNormalMap;
#endif
-#ifdef ENABLE_DAYNIGHT_SHADING
+#if defined(ENABLE_DAYNIGHT_SHADING) || defined(GROUND_ATMOSPHERE)
uniform vec2 u_lightingFadeDistance;
#endif
@@ -55,13 +54,17 @@ uniform vec2 u_lightingFadeDistance;
uniform vec4 u_cartographicLimitRectangle;
#endif
+#ifdef GROUND_ATMOSPHERE
+uniform vec2 u_nightFadeDistance;
+#endif
+
#ifdef ENABLE_CLIPPING_PLANES
uniform sampler2D u_clippingPlanes;
uniform mat4 u_clippingPlanesMatrix;
uniform vec4 u_clippingPlanesEdgeStyle;
#endif
-#if defined(FOG) && (defined(ENABLE_VERTEX_LIGHTING) || defined(ENABLE_DAYNIGHT_SHADING))
+#if defined(FOG) && (defined(ENABLE_VERTEX_LIGHTING) || defined(ENABLE_DAYNIGHT_SHADING)) || defined(GROUND_ATMOSPHERE)
uniform float u_minimumBrightness;
#endif
@@ -76,8 +79,13 @@ varying float v_height;
varying float v_slope;
#endif
-#ifdef FOG
+#if defined(FOG) || defined(GROUND_ATMOSPHERE)
varying float v_distance;
+varying vec3 v_fogRayleighColor;
+varying vec3 v_fogMieColor;
+#endif
+
+#ifdef GROUND_ATMOSPHERE
varying vec3 v_rayleighColor;
varying vec3 v_mieColor;
#endif
@@ -155,7 +163,7 @@ vec4 sampleAndBlend(
}
vec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates);
-vec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat3 enuToEye, vec4 imageryColor, float specularMapValue);
+vec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat3 enuToEye, vec4 imageryColor, float specularMapValue, float fade);
void main()
{
@@ -191,6 +199,33 @@ void main()
vec3 normalEC = czm_normal3D * normalMC; // normalized surface normal in eye coordiantes
#endif
+#if defined(ENABLE_DAYNIGHT_SHADING) || defined(GROUND_ATMOSPHERE)
+ float cameraDist;
+ if (czm_sceneMode == czm_sceneMode2D)
+ {
+ cameraDist = max(czm_frustumPlanes.x - czm_frustumPlanes.y, czm_frustumPlanes.w - czm_frustumPlanes.z) * 0.5;
+ }
+ else if (czm_sceneMode == czm_sceneModeColumbusView)
+ {
+ cameraDist = -czm_view[3].z;
+ }
+ else
+ {
+ cameraDist = length(czm_view[3]);
+ }
+ float fadeOutDist = u_lightingFadeDistance.x;
+ float fadeInDist = u_lightingFadeDistance.y;
+ if (czm_sceneMode != czm_sceneMode3D) {
+ vec3 radii = czm_getWgs84EllipsoidEC().radii;
+ float maxRadii = max(radii.x, max(radii.y, radii.z));
+ fadeOutDist -= maxRadii;
+ fadeInDist -= maxRadii;
+ }
+ float fade = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.0, 1.0);
+#else
+ float fade = 0.0;
+#endif
+
#ifdef SHOW_REFLECTIVE_OCEAN
vec2 waterMaskTranslation = u_waterMaskTranslationAndScale.xy;
vec2 waterMaskScale = u_waterMaskTranslationAndScale.zw;
@@ -208,7 +243,7 @@ void main()
vec2 textureCoordinates = mix(ellipsoidTextureCoordinates, ellipsoidFlippedTextureCoordinates, czm_morphTime * smoothstep(0.9, 0.95, normalMC.z));
- color = computeWaterColor(v_positionEC, textureCoordinates, enuToEye, color, mask);
+ color = computeWaterColor(v_positionEC, textureCoordinates, enuToEye, color, mask, fade);
}
#endif
@@ -222,34 +257,12 @@ void main()
color.xyz = mix(color.xyz, material.diffuse, material.alpha);
#endif
-#ifdef ENABLE_VERTEX_LIGHTING
+#if defined(ENABLE_VERTEX_LIGHTING)
float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalize(v_normalEC)) * 0.9 + 0.3, 0.0, 1.0);
vec4 finalColor = vec4(color.rgb * diffuseIntensity, color.a);
#elif defined(ENABLE_DAYNIGHT_SHADING)
float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * 5.0 + 0.3, 0.0, 1.0);
- float cameraDist;
- if (czm_sceneMode == czm_sceneMode2D)
- {
- cameraDist = max(czm_frustumPlanes.x - czm_frustumPlanes.y, czm_frustumPlanes.w - czm_frustumPlanes.z) * 0.5;
- }
- else if (czm_sceneMode == czm_sceneModeColumbusView)
- {
- cameraDist = -czm_view[3].z;
- }
- else
- {
- cameraDist = length(czm_view[3]);
- }
- float fadeOutDist = u_lightingFadeDistance.x;
- float fadeInDist = u_lightingFadeDistance.y;
- if (czm_sceneMode != czm_sceneMode3D) {
- vec3 radii = czm_getWgs84EllipsoidEC().radii;
- float maxRadii = max(radii.x, max(radii.y, radii.z));
- fadeOutDist -= maxRadii;
- fadeInDist -= maxRadii;
- }
- float t = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.0, 1.0);
- diffuseIntensity = mix(1.0, diffuseIntensity, t);
+ diffuseIntensity = mix(1.0, diffuseIntensity, fade);
vec4 finalColor = vec4(color.rgb * diffuseIntensity, color.a);
#else
vec4 finalColor = color;
@@ -266,20 +279,60 @@ void main()
}
#endif
-#ifdef FOG
+#if defined(FOG) || defined(GROUND_ATMOSPHERE)
const float fExposure = 2.0;
- vec3 fogColor = v_mieColor + finalColor.rgb * v_rayleighColor;
+ vec3 fogColor = v_fogMieColor + finalColor.rgb * v_fogRayleighColor;
fogColor = vec3(1.0) - exp(-fExposure * fogColor);
+#endif
+#ifdef FOG
#if defined(ENABLE_VERTEX_LIGHTING) || defined(ENABLE_DAYNIGHT_SHADING)
float darken = clamp(dot(normalize(czm_viewerPositionWC), normalize(czm_sunPositionWC)), u_minimumBrightness, 1.0);
fogColor *= darken;
#endif
- gl_FragColor = vec4(czm_fog(v_distance, finalColor.rgb, fogColor), finalColor.a);
+ finalColor = vec4(czm_fog(v_distance, finalColor.rgb, fogColor), finalColor.a);
+#endif
+
+#ifdef GROUND_ATMOSPHERE
+ if (czm_sceneMode != czm_sceneMode3D)
+ {
+ gl_FragColor = finalColor;
+ return;
+ }
+
+#if defined(PER_FRAGMENT_GROUND_ATMOSPHERE) && (defined(ENABLE_DAYNIGHT_SHADING) || defined(ENABLE_VERTEX_LIGHTING))
+ czm_ellipsoid ellipsoid = czm_getWgs84EllipsoidEC();
+
+ float mpp = czm_metersPerPixel(vec4(0.0, 0.0, -czm_currentFrustum.x, 1.0));
+ vec2 xy = gl_FragCoord.xy / czm_viewport.zw * 2.0 - vec2(1.0);
+ xy *= czm_viewport.zw * mpp * 0.5;
+
+ vec3 direction = normalize(vec3(xy, -czm_currentFrustum.x));
+ czm_ray ray = czm_ray(vec3(0.0), direction);
+
+ czm_raySegment intersection = czm_rayEllipsoidIntersectionInterval(ray, ellipsoid);
+
+ vec3 ellipsoidPosition = czm_pointAlongRay(ray, intersection.start);
+ ellipsoidPosition = (czm_inverseView * vec4(ellipsoidPosition, 1.0)).xyz;
+ AtmosphereColor atmosColor = computeGroundAtmosphereFromSpace(ellipsoidPosition, true);
+
+ vec3 groundAtmosphereColor = atmosColor.mie + finalColor.rgb * atmosColor.rayleigh;
+ groundAtmosphereColor = vec3(1.0) - exp(-fExposure * groundAtmosphereColor);
+
+ fadeInDist = u_nightFadeDistance.x;
+ fadeOutDist = u_nightFadeDistance.y;
+
+ float sunlitAtmosphereIntensity = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.0, 1.0);
+ groundAtmosphereColor = mix(groundAtmosphereColor, fogColor, sunlitAtmosphereIntensity);
#else
- gl_FragColor = finalColor;
+ vec3 groundAtmosphereColor = fogColor;
#endif
+
+ finalColor = vec4(mix(finalColor.rgb, groundAtmosphereColor, fade), finalColor.a);
+#endif
+
+ gl_FragColor = finalColor;
}
#ifdef SHOW_REFLECTIVE_OCEAN
@@ -309,7 +362,7 @@ const float oceanFrequencyHighAltitude = 125000.0;
const float oceanAnimationSpeedHighAltitude = 0.008;
const float oceanOneOverAmplitudeHighAltitude = 1.0 / 2.0;
-vec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat3 enuToEye, vec4 imageryColor, float maskValue)
+vec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat3 enuToEye, vec4 imageryColor, float maskValue, float fade)
{
vec3 positionToEyeEC = -positionEyeCoordinates;
float positionToEyeECLength = length(positionToEyeEC);
@@ -352,7 +405,7 @@ vec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat
// Use diffuse light to highlight the waves
float diffuseIntensity = czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * maskValue;
- vec3 diffuseHighlight = waveHighlightColor * diffuseIntensity;
+ vec3 diffuseHighlight = waveHighlightColor * diffuseIntensity * (1.0 - fade);
#ifdef SHOW_OCEAN_WAVES
// Where diffuse light is low or non-existent, use wave highlights based solely on
diff --git a/Source/Shaders/GlobeVS.glsl b/Source/Shaders/GlobeVS.glsl
index 30c2afc014a6..f7c1bb25263e 100644
--- a/Source/Shaders/GlobeVS.glsl
+++ b/Source/Shaders/GlobeVS.glsl
@@ -27,10 +27,10 @@ varying float v_slope;
varying float v_height;
#endif
-#ifdef FOG
+#if defined(FOG) || defined(GROUND_ATMOSPHERE)
varying float v_distance;
-varying vec3 v_mieColor;
-varying vec3 v_rayleighColor;
+varying vec3 v_fogMieColor;
+varying vec3 v_fogRayleighColor;
#endif
// These functions are generated at runtime.
@@ -158,19 +158,19 @@ void main()
#if defined(ENABLE_VERTEX_LIGHTING) || defined(GENERATE_POSITION_AND_NORMAL) || defined(APPLY_MATERIAL)
v_positionEC = (u_modifiedModelView * vec4(position, 1.0)).xyz;
- v_positionMC = position3DWC; // position in model coordinates
+ v_positionMC = position3DWC; // position in model coordinates
vec3 normalMC = czm_octDecode(encodedNormal);
v_normalMC = normalMC;
v_normalEC = czm_normal3D * v_normalMC;
#elif defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) || defined(GENERATE_POSITION)
v_positionEC = (u_modifiedModelView * vec4(position, 1.0)).xyz;
- v_positionMC = position3DWC; // position in model coordinates
+ v_positionMC = position3DWC; // position in model coordinates
#endif
-#ifdef FOG
- AtmosphereColor atmosColor = computeGroundAtmosphereFromSpace(position3DWC);
- v_mieColor = atmosColor.mie;
- v_rayleighColor = atmosColor.rayleigh;
+#if defined(FOG) || defined(GROUND_ATMOSPHERE)
+ AtmosphereColor atmosFogColor = computeGroundAtmosphereFromSpace(position3DWC, false);
+ v_fogMieColor = atmosFogColor.mie;
+ v_fogRayleighColor = atmosFogColor.rayleigh;
v_distance = length((czm_modelView3D * vec4(position3DWC, 1.0)).xyz);
#endif
diff --git a/Source/Shaders/GroundAtmosphere.glsl b/Source/Shaders/GroundAtmosphere.glsl
index 98115f017b5a..4ac25eead7f3 100644
--- a/Source/Shaders/GroundAtmosphere.glsl
+++ b/Source/Shaders/GroundAtmosphere.glsl
@@ -3,11 +3,11 @@
*
* Copyright (c) 2000-2005, Sean O'Neil (s_p_oneil@hotmail.com)
* All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
+ *
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
@@ -16,7 +16,7 @@
* * Neither the name of the project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -30,7 +30,7 @@
*
* Modifications made by Analytical Graphics, Inc.
*/
-
+
// Atmosphere:
// Code: http://sponeil.net/
// GPU Gems 2 Article: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html
@@ -67,7 +67,7 @@ float scale(float fCos)
return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
}
-AtmosphereColor computeGroundAtmosphereFromSpace(vec3 v3Pos)
+AtmosphereColor computeGroundAtmosphereFromSpace(vec3 v3Pos, bool useSunLighting)
{
vec3 v3InvWavelength = vec3(1.0 / pow(0.650, 4.0), 1.0 / pow(0.570, 4.0), 1.0 / pow(0.475, 4.0));
@@ -75,11 +75,11 @@ AtmosphereColor computeGroundAtmosphereFromSpace(vec3 v3Pos)
vec3 v3Ray = v3Pos - czm_viewerPositionWC;
float fFar = length(v3Ray);
v3Ray /= fFar;
-
+
float fCameraHeight = length(czm_viewerPositionWC);
float fCameraHeight2 = fCameraHeight * fCameraHeight;
- // This next line is an ANGLE workaround. It is equivalent to B = 2.0 * dot(czm_viewerPositionWC, v3Ray),
+ // This next line is an ANGLE workaround. It is equivalent to B = 2.0 * dot(czm_viewerPositionWC, v3Ray),
// which is what it should be, but there are problems at the poles.
float B = 2.0 * length(czm_viewerPositionWC) * dot(normalize(czm_viewerPositionWC), v3Ray);
float C = fCameraHeight2 - fOuterRadius2;
@@ -90,11 +90,11 @@ AtmosphereColor computeGroundAtmosphereFromSpace(vec3 v3Pos)
vec3 v3Start = czm_viewerPositionWC + v3Ray * fNear;
fFar -= fNear;
float fDepth = exp((fInnerRadius - fOuterRadius) / fScaleDepth);
-
+
// The light angle based on the sun position would be:
// dot(czm_sunDirectionWC, v3Pos) / length(v3Pos);
- // We want the atmosphere to be uniform over the globe so it is set to 1.0.
- float fLightAngle = 1.0;
+ // When we want the atmosphere to be uniform over the globe so it is set to 1.0.
+ float fLightAngle = useSunLighting ? dot(czm_sunDirectionWC, v3Pos) / length(v3Pos) : 1.0;
float fCameraAngle = dot(-v3Ray, v3Pos) / length(v3Pos);
float fCameraScale = scale(fCameraAngle);
float fLightScale = scale(fLightAngle);
@@ -119,11 +119,11 @@ AtmosphereColor computeGroundAtmosphereFromSpace(vec3 v3Pos)
v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
v3SamplePoint += v3SampleRay;
}
-
+
AtmosphereColor color;
color.mie = v3FrontColor * (v3InvWavelength * fKrESun + fKmESun);
color.rayleigh = v3Attenuate; // Calculate the attenuation factor for the ground
-
+
return color;
}
diff --git a/Source/Shaders/SkyAtmosphereFS.glsl b/Source/Shaders/SkyAtmosphereFS.glsl
index 678ec9b35432..52935fbe6986 100644
--- a/Source/Shaders/SkyAtmosphereFS.glsl
+++ b/Source/Shaders/SkyAtmosphereFS.glsl
@@ -58,8 +58,6 @@ void main (void)
vec3 rgb = rayleighPhase * v_rayleighColor + miePhase * v_mieColor;
rgb = vec3(1.0) - exp(-exposure * rgb);
- // Compute luminance before color correction to avoid strangely gray night skies
- float l = czm_luminance(rgb);
#ifdef COLOR_CORRECT
// Convert rgb color to hsb
@@ -70,9 +68,6 @@ void main (void)
hsb.z = hsb.z > czm_epsilon7 ? hsb.z + u_hsbShift.z : 0.0; // brightness
// Convert shifted hsb back to rgb
rgb = czm_HSBToRGB(hsb);
-
- // Check if correction decreased the luminance to 0
- l = min(l, czm_luminance(rgb));
#endif
// Alter alpha based on how close the viewer is to the ground (1.0 = on ground, 0.0 = at edge of atmosphere)