Skip to content

Commit

Permalink
Merge pull request #8868 from epranka/day-night-textures
Browse files Browse the repository at this point in the history
dayAlpha and nightAlpha in the ImageryLayer
  • Loading branch information
IanLilleyT authored Jun 1, 2020
2 parents 38bb637 + e3b0f02 commit 746f8ac
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 11 deletions.
34 changes: 34 additions & 0 deletions Apps/Sandcastle/gallery/Earth at Night.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,40 @@
var viewer = new Cesium.Viewer("cesiumContainer", {
imageryProvider: new Cesium.IonImageryProvider({ assetId: 3812 }),
});

// The rest of the code is for dynamic lighting
var dynamicLighting = false;

viewer.clock.multiplier = 4000;

var imageryLayers = viewer.imageryLayers;
var nightLayer = imageryLayers.get(0);
var dayLayer = imageryLayers.addImageryProvider(
new Cesium.IonImageryProvider({
assetId: 3845,
})
);
imageryLayers.lowerToBottom(dayLayer);

function updateLighting(dynamicLighting) {
dayLayer.show = dynamicLighting;
viewer.scene.globe.enableLighting = dynamicLighting;
viewer.clock.shouldAnimate = dynamicLighting;

// If dynamic lighting is enabled, make the night imagery invisible
// on the lit side of the globe.
nightLayer.dayAlpha = dynamicLighting ? 0.0 : 1.0;
}

updateLighting(dynamicLighting);

Sandcastle.addToggleButton(
"Dynamic lighting",
dynamicLighting,
function (checked) {
updateLighting(checked);
}
);
//Sandcastle_End
Sandcastle.finishedLoading();
}
Expand Down
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
- Added `Cesium3DTileset.extensions` to get the extensions property from the tileset JSON. [#8829](https://github.com/CesiumGS/cesium/pull/8829)
- Added `frustumSplits` option to `DebugCameraPrimitive`. [8849](https://github.com/CesiumGS/cesium/pull/8849)
- Added `SkyAtmosphere.perFragmentAtmosphere` to switch between per-vertex and per-fragment atmosphere shading. [#8866](https://github.com/CesiumGS/cesium/pull/8866)
- Added `Globe.undergroundColor` and `Globe.undergroundColorAlphaByDistance` for controlling how the back side of the globe is rendered when the camera is underground or the globe is translucent. [#8867](https://github.com/CesiumGS/cesium/pull/8867)
- Added `nightAlpha` and `dayAlpha` properties to `ImageryLayer` to control alpha separately for the night and day sides of the globe. [#8868](https://github.com/CesiumGS/cesium/pull/8868)
- Added a new sandcastle example to show how to add fog using a `PostProcessStage` [#8798](https://github.com/CesiumGS/cesium/pull/8798)
- Supported `#rgba` and `#rrggbbaa` formats in `Color.fromCssColorString`. [8873](https://github.com/CesiumGS/cesium/pull/8873)
- Added `Camera.completeFlight`, which causes the current camera flight to immediately jump to the final destination and call its complete callback. [#8788](https://github.com/CesiumGS/cesium/pull/8788)
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,4 +256,5 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu
- [SungHo Lim](https://github.com/SambaLim)
- [Michael Fink](https://github.com/vividos)
- [Jakub Vrana](https://github.com/vrana)
- [Edvinas Pranka](https://github.com/epranka)
- [James Bromwell](https://github.com/thw0rted)
16 changes: 13 additions & 3 deletions Source/Scene/GlobeSurfaceShaderSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
var applySaturation = options.applySaturation;
var applyGamma = options.applyGamma;
var applyAlpha = options.applyAlpha;
var applyDayNightAlpha = options.applyDayNightAlpha;
var applySplit = options.applySplit;
var showReflectiveOcean = options.showReflectiveOcean;
var showOceanWaves = options.showOceanWaves;
Expand Down Expand Up @@ -155,7 +156,8 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
(highlightFillTile << 24) |
(colorToAlpha << 25) |
(showUndergroundColor << 26) |
(translucent << 27);
(translucent << 27) |
(applyDayNightAlpha << 28);

var currentClippingShaderState = 0;
if (defined(clippingPlanes) && clippingPlanes.length > 0) {
Expand Down Expand Up @@ -221,6 +223,9 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
if (applyAlpha) {
fs.defines.push("APPLY_ALPHA");
}
if (applyDayNightAlpha) {
fs.defines.push("APPLY_DAY_NIGHT_ALPHA");
}
if (showReflectiveOcean) {
fs.defines.push("SHOW_REFLECTIVE_OCEAN");
vs.defines.push("SHOW_REFLECTIVE_OCEAN");
Expand Down Expand Up @@ -290,7 +295,7 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {

var computeDayColor =
"\
vec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates)\n\
vec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates, float nightBlend)\n\
{\n\
vec4 color = initialColor;\n";

Expand Down Expand Up @@ -333,6 +338,10 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
(applyAlpha ? "u_dayTextureAlpha[" + i + "]" : "1.0") +
",\n\
" +
(applyDayNightAlpha ? "u_dayTextureNightAlpha[" + i + "]" : "1.0") +
",\n" +
(applyDayNightAlpha ? "u_dayTextureDayAlpha[" + i + "]" : "1.0") +
",\n" +
(applyBrightness ? "u_dayTextureBrightness[" + i + "]" : "0.0") +
",\n\
" +
Expand All @@ -352,7 +361,8 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
",\n\
" +
(colorToAlpha ? "u_colorsToAlpha[" + i + "]" : "vec4(0.0)") +
"\n\
",\n\
nightBlend\
);\n";
if (hasImageryLayerCutout) {
computeDayColor +=
Expand Down
23 changes: 23 additions & 0 deletions Source/Scene/GlobeSurfaceTileProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -1560,6 +1560,12 @@ function createTileUniformMap(frameState, globeSurfaceTileProvider) {
u_dayTextureAlpha: function () {
return this.properties.dayTextureAlpha;
},
u_dayTextureNightAlpha: function () {
return this.properties.dayTextureNightAlpha;
},
u_dayTextureDayAlpha: function () {
return this.properties.dayTextureDayAlpha;
},
u_dayTextureBrightness: function () {
return this.properties.dayTextureBrightness;
},
Expand Down Expand Up @@ -1674,6 +1680,8 @@ function createTileUniformMap(frameState, globeSurfaceTileProvider) {
dayTextureTexCoordsRectangle: [],
dayTextureUseWebMercatorT: [],
dayTextureAlpha: [],
dayTextureNightAlpha: [],
dayTextureDayAlpha: [],
dayTextureBrightness: [],
dayTextureContrast: [],
dayTextureHue: [],
Expand Down Expand Up @@ -1880,6 +1888,7 @@ var surfaceShaderSetOptionsScratch = {
applySaturation: undefined,
applyGamma: undefined,
applyAlpha: undefined,
applyDayNightAlpha: undefined,
applySplit: undefined,
showReflectiveOcean: undefined,
showOceanWaves: undefined,
Expand Down Expand Up @@ -2324,6 +2333,7 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
var applySaturation = false;
var applyGamma = false;
var applyAlpha = false;
var applyDayNightAlpha = false;
var applySplit = false;
var applyCutout = false;
var applyColorToAlpha = false;
Expand Down Expand Up @@ -2380,6 +2390,18 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
applyAlpha ||
uniformMapProperties.dayTextureAlpha[numberOfDayTextures] !== 1.0;

uniformMapProperties.dayTextureNightAlpha[numberOfDayTextures] =
imageryLayer.nightAlpha;
applyDayNightAlpha =
applyDayNightAlpha ||
uniformMapProperties.dayTextureNightAlpha[numberOfDayTextures] !== 1.0;

uniformMapProperties.dayTextureDayAlpha[numberOfDayTextures] =
imageryLayer.dayAlpha;
applyDayNightAlpha =
applyDayNightAlpha ||
uniformMapProperties.dayTextureDayAlpha[numberOfDayTextures] !== 1.0;

uniformMapProperties.dayTextureBrightness[numberOfDayTextures] =
imageryLayer.brightness;
applyBrightness =
Expand Down Expand Up @@ -2527,6 +2549,7 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
surfaceShaderSetOptions.applySaturation = applySaturation;
surfaceShaderSetOptions.applyGamma = applyGamma;
surfaceShaderSetOptions.applyAlpha = applyAlpha;
surfaceShaderSetOptions.applyDayNightAlpha = applyDayNightAlpha;
surfaceShaderSetOptions.applySplit = applySplit;
surfaceShaderSetOptions.enableFog = applyFog;
surfaceShaderSetOptions.enableClippingPlanes = clippingPlanesEnabled;
Expand Down
36 changes: 36 additions & 0 deletions Source/Scene/ImageryLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@ import TileImagery from "./TileImagery.js";
* current frame state, this layer, and the x, y, and level coordinates of the
* imagery tile for which the alpha is required, and it is expected to return
* the alpha value to use for the tile.
* @param {Number|Function} [options.nightAlpha=1.0] The alpha blending value of this layer on the night side of the globe, from 0.0 to 1.0.
* This can either be a simple number or a function with the signature
* <code>function(frameState, layer, x, y, level)</code>. The function is passed the
* current frame state, this layer, and the x, y, and level coordinates of the
* imagery tile for which the alpha is required, and it is expected to return
* the alpha value to use for the tile. This only takes effect when <code>enableLighting</code> is <code>true</code>.
* @param {Number|Function} [options.dayAlpha=1.0] The alpha blending value of this layer on the day side of the globe, from 0.0 to 1.0.
* This can either be a simple number or a function with the signature
* <code>function(frameState, layer, x, y, level)</code>. The function is passed the
* current frame state, this layer, and the x, y, and level coordinates of the
* imagery tile for which the alpha is required, and it is expected to return
* the alpha value to use for the tile. This only takes effect when <code>enableLighting</code> is <code>true</code>.
* @param {Number|Function} [options.brightness=1.0] The brightness of this layer. 1.0 uses the unmodified imagery
* color. Less than 1.0 makes the imagery darker while greater than 1.0 makes it brighter.
* This can either be a simple number or a function with the signature
Expand Down Expand Up @@ -131,6 +143,30 @@ function ImageryLayer(imageryProvider, options) {
defaultValue(imageryProvider.defaultAlpha, 1.0)
);

/**
* The alpha blending value of this layer on the night side of the globe, with 0.0 representing fully transparent and
* 1.0 representing fully opaque. This only takes effect when {@link Globe#enableLighting} is <code>true</code>.
*
* @type {Number}
* @default 1.0
*/
this.nightAlpha = defaultValue(
options.nightAlpha,
defaultValue(imageryProvider.defaultNightAlpha, 1.0)
);

/**
* The alpha blending value of this layer on the day side of the globe, with 0.0 representing fully transparent and
* 1.0 representing fully opaque. This only takes effect when {@link Globe#enableLighting} is <code>true</code>.
*
* @type {Number}
* @default 1.0
*/
this.dayAlpha = defaultValue(
options.dayAlpha,
defaultValue(imageryProvider.defaultDayAlpha, 1.0)
);

/**
* The brightness of this layer. 1.0 uses the unmodified imagery color. Less than 1.0
* makes the imagery darker while greater than 1.0 makes it brighter.
Expand Down
18 changes: 18 additions & 0 deletions Source/Scene/ImageryProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ function ImageryProvider() {
*/
this.defaultAlpha = undefined;

/**
* The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
* 1.0 representing fully opaque.
*
* @type {Number}
* @default undefined
*/
this.defaultNightAlpha = undefined;

/**
* The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
* 1.0 representing fully opaque.
*
* @type {Number}
* @default undefined
*/
this.defaultDayAlpha = undefined;

/**
* The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
* makes the imagery darker while greater than 1.0 makes it brighter.
Expand Down
34 changes: 26 additions & 8 deletions Source/Shaders/GlobeFS.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ uniform bool u_dayTextureUseWebMercatorT[TEXTURE_UNITS];
uniform float u_dayTextureAlpha[TEXTURE_UNITS];
#endif

#ifdef APPLY_DAY_NIGHT_ALPHA
uniform float u_dayTextureNightAlpha[TEXTURE_UNITS];
uniform float u_dayTextureDayAlpha[TEXTURE_UNITS];
#endif

#ifdef APPLY_SPLIT
uniform float u_dayTextureSplit[TEXTURE_UNITS];
#endif
Expand Down Expand Up @@ -158,13 +163,16 @@ vec4 sampleAndBlend(
vec4 textureCoordinateRectangle,
vec4 textureCoordinateTranslationAndScale,
float textureAlpha,
float textureNightAlpha,
float textureDayAlpha,
float textureBrightness,
float textureContrast,
float textureHue,
float textureSaturation,
float textureOneOverGamma,
float split,
vec4 colorToAlpha)
vec4 colorToAlpha,
float nightBlend)
{
// This crazy step stuff sets the alpha to 0.0 if this following condition is true:
// tileTextureCoordinates.s < textureCoordinateRectangle.s ||
Expand All @@ -179,6 +187,10 @@ vec4 sampleAndBlend(
alphaMultiplier = step(vec2(0.0), textureCoordinateRectangle.pq - tileTextureCoordinates);
textureAlpha = textureAlpha * alphaMultiplier.x * alphaMultiplier.y;

#if defined(APPLY_DAY_NIGHT_ALPHA) && defined(ENABLE_DAYNIGHT_SHADING)
textureAlpha *= mix(textureDayAlpha, textureNightAlpha, nightBlend);
#endif

vec2 translation = textureCoordinateTranslationAndScale.xy;
vec2 scale = textureCoordinateTranslationAndScale.zw;
vec2 textureCoordinates = tileTextureCoordinates * scale + translation;
Expand Down Expand Up @@ -269,7 +281,7 @@ vec3 colorCorrect(vec3 rgb) {
return rgb;
}

vec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates);
vec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates, float nightBlend);
vec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat3 enuToEye, vec4 imageryColor, float specularMapValue, float fade);

#ifdef GROUND_ATMOSPHERE
Expand All @@ -292,11 +304,22 @@ void main()
float clipDistance = clip(gl_FragCoord, u_clippingPlanes, u_clippingPlanesMatrix);
#endif

#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) || defined(HDR)
vec3 normalMC = czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)); // normalized surface normal in model coordinates
vec3 normalEC = czm_normal3D * normalMC; // normalized surface normal in eye coordiantes
#endif

#if defined(APPLY_DAY_NIGHT_ALPHA) && defined(ENABLE_DAYNIGHT_SHADING)
float nightBlend = 1.0 - clamp(czm_getLambertDiffuse(czm_lightDirectionEC, normalEC) * 5.0, 0.0, 1.0);
#else
float nightBlend = 0.0;
#endif

// The clamp below works around an apparent bug in Chrome Canary v23.0.1241.0
// where the fragment shader sees textures coordinates < 0.0 and > 1.0 for the
// fragments on the edges of tiles even though the vertex shader is outputting
// coordinates strictly in the 0-1 range.
vec4 color = computeDayColor(u_initialColor, clamp(v_textureCoordinates, 0.0, 1.0));
vec4 color = computeDayColor(u_initialColor, clamp(v_textureCoordinates, 0.0, 1.0), nightBlend);

#ifdef SHOW_TILE_BOUNDARIES
if (v_textureCoordinates.x < (1.0/256.0) || v_textureCoordinates.x > (255.0/256.0) ||
Expand All @@ -306,11 +329,6 @@ void main()
}
#endif

#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) || defined(HDR)
vec3 normalMC = czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)); // normalized surface normal in model coordinates
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)
Expand Down
4 changes: 4 additions & 0 deletions Specs/Scene/GlobeSurfaceTileProviderSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,8 @@ describe(
);

layer.alpha = 0.123;
layer.nightAlpha = 0.658;
layer.dayAlpha = 0.356;
layer.brightness = 0.456;
layer.contrast = 0.654;
layer.gamma = 0.321;
Expand Down Expand Up @@ -651,6 +653,8 @@ describe(
++tileCommandCount;

expect(uniforms.u_dayTextureAlpha()).toEqual([0.123]);
expect(uniforms.u_dayTextureNightAlpha()).toEqual([0.658]);
expect(uniforms.u_dayTextureDayAlpha()).toEqual([0.356]);
expect(uniforms.u_dayTextureBrightness()).toEqual([0.456]);
expect(uniforms.u_dayTextureContrast()).toEqual([0.654]);
expect(uniforms.u_dayTextureOneOverGamma()).toEqual([1.0 / 0.321]);
Expand Down

0 comments on commit 746f8ac

Please sign in to comment.