Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dayAlpha and nightAlpha in the ImageryLayer #8868

Merged
merged 9 commits into from
Jun 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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