From c09945b94bd54b67c0467c29c3856c8a61971d6a Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Sat, 23 May 2020 12:39:31 -0400 Subject: [PATCH] Added GlobeTranslucency to group translucency options --- Apps/Sandcastle/gallery/Globe Interior.html | 14 +- .../gallery/Globe Translucency.html | 8 +- CHANGES.md | 8 +- Source/Scene/Globe.js | 218 +--------------- Source/Scene/GlobeSurfaceTileProvider.js | 14 +- Source/Scene/GlobeTranslucency.js | 238 ++++++++++++++++++ Source/Scene/GlobeTranslucencyState.js | 33 ++- Specs/Scene/GlobeTranslucencyStateSpec.js | 137 +++++----- Specs/Scene/SceneSpec.js | 22 +- 9 files changed, 368 insertions(+), 324 deletions(-) create mode 100644 Source/Scene/GlobeTranslucency.js diff --git a/Apps/Sandcastle/gallery/Globe Interior.html b/Apps/Sandcastle/gallery/Globe Interior.html index d5b6d352f414..9560ac61dff2 100644 --- a/Apps/Sandcastle/gallery/Globe Interior.html +++ b/Apps/Sandcastle/gallery/Globe Interior.html @@ -48,17 +48,17 @@ function reset() { globe.showGroundAtmosphere = true; globe.baseColor = Cesium.Color.BLUE; - globe.translucencyEnabled = false; - globe.frontFaceAlpha = 1.0; + globe.translucency.enabled = false; + globe.translucency.frontFaceAlpha = 1.0; globe.undergroundColor = Cesium.Color.BLACK; - globe.translucencyRectangle = undefined; + globe.translucency.rectangle = undefined; baseLayer.colorToAlpha = undefined; } function useTranslucencyMask() { globe.showGroundAtmosphere = false; globe.baseColor = Cesium.Color.TRANSPARENT; - globe.translucencyEnabled = true; + globe.translucency.enabled = true; globe.undergroundColor = undefined; // Set oceans on Bing base layer to transparent @@ -67,10 +67,10 @@ } function useTranslucencyRectangle() { - globe.translucencyEnabled = true; + globe.translucency.enabled = true; globe.undergroundColor = undefined; - globe.frontFaceAlpha = 0.25; - globe.translucencyRectangle = Cesium.Rectangle.fromDegrees( + globe.translucency.frontFaceAlpha = 0.25; + globe.translucency.rectangle = Cesium.Rectangle.fromDegrees( -120.0, 0.0, -30.0, diff --git a/Apps/Sandcastle/gallery/Globe Translucency.html b/Apps/Sandcastle/gallery/Globe Translucency.html index 89a7f0fd2c04..2cb67a4ceff8 100644 --- a/Apps/Sandcastle/gallery/Globe Translucency.html +++ b/Apps/Sandcastle/gallery/Globe Translucency.html @@ -92,7 +92,7 @@ var globe = scene.globe; scene.screenSpaceCameraController.enableCollisionDetection = false; - globe.frontFaceAlphaByDistance = new Cesium.NearFarScalar( + globe.translucency.frontFaceAlphaByDistance = new Cesium.NearFarScalar( 400.0, 0.0, 800.0, @@ -258,14 +258,14 @@ } function update() { - globe.translucencyEnabled = viewModel.translucencyEnabled; + globe.translucency.enabled = viewModel.translucencyEnabled; var alpha = Number(viewModel.alpha); alpha = !isNaN(alpha) ? alpha : 1.0; alpha = Cesium.Math.clamp(alpha, 0.0, 1.0); - globe.frontFaceAlphaByDistance.nearValue = alpha; - globe.frontFaceAlphaByDistance.farValue = viewModel.fadeByDistance + globe.translucency.frontFaceAlphaByDistance.nearValue = alpha; + globe.translucency.frontFaceAlphaByDistance.farValue = viewModel.fadeByDistance ? 1.0 : alpha; diff --git a/CHANGES.md b/CHANGES.md index 4284331b7fb7..4a5c3a43d161 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,10 +5,10 @@ ##### Additions :tada: - Added support for rendering the globe with translucency. [#8726](https://github.com/CesiumGS/cesium/pull/8726) - - Added `Globe.translucencyEnabled` for enabling globe translucency. - - Added `Globe.frontFaceAlpha` and `Globe.frontFaceAlphaByDistance` for controlling the alpha of front faces. - - Added `Globe.backFaceAlpha` and `Globe.backFaceAlphaByDistance` for controlling the alpha of back faces. - - Added `Globe.translucencyRectangle` for applying translucency only within a rectangular area. + - Added `globe.translucency.enabled` to enable globe translucency. + - Added `globe.translucency.frontFaceAlpha` and `globe.translucency.frontFaceAlphaByDistance` for controlling the alpha of front faces. + - Added `globe.translucency.backFaceAlpha` and `globe.translucency.backFaceAlphaByDistance` for controlling the alpha of back faces. + - Added `globe.translucency.rectangle` for applying translucency only within a rectangular area. - 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) diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index 3fc9aa528ab4..9a42146beaca 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -2,7 +2,6 @@ import BoundingSphere from "../Core/BoundingSphere.js"; import buildModuleUrl from "../Core/buildModuleUrl.js"; import Cartesian3 from "../Core/Cartesian3.js"; import Cartographic from "../Core/Cartographic.js"; -import Check from "../Core/Check.js"; import Color from "../Core/Color.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; @@ -24,6 +23,7 @@ import GroundAtmosphere from "../Shaders/GroundAtmosphere.js"; import when from "../ThirdParty/when.js"; import GlobeSurfaceShaderSet from "./GlobeSurfaceShaderSet.js"; import GlobeSurfaceTileProvider from "./GlobeSurfaceTileProvider.js"; +import GlobeTranslucency from "./GlobeTranslucency.js"; import ImageryLayerCollection from "./ImageryLayerCollection.js"; import QuadtreePrimitive from "./QuadtreePrimitive.js"; import SceneMode from "./SceneMode.js"; @@ -71,11 +71,7 @@ function Globe(ellipsoid) { 1.0 ); - this._translucencyEnabled = false; - this._frontFaceAlpha = 1.0; - this._frontFaceAlphaByDistance = undefined; - this._backFaceAlpha = 1.0; - this._backFaceAlphaByDistance = undefined; + this._translucency = new GlobeTranslucency(); makeShadersDirty(this); @@ -545,216 +541,14 @@ Object.defineProperties(Globe.prototype, { }, /** - * When true, the globe is rendered as a translucent surface. - *

- * The alpha is computed by blending {@link Globe#material}, {@link Globe#imageryLayers}, - * and {@link Globe#baseColor}, all of which may contain translucency, and then multiplying by - * {@link Globe#frontFaceAlpha} and {@link Globe#frontFaceAlphaByDistance} for front faces and - * {@link Globe#backFaceAlpha} and {@link Globe#backFaceAlphaByDistance} for back faces. - * When the camera is underground back faces and front faces are swapped, i.e. back-facing geometry - * is considered front facing. - *

- * Translucency is disabled by default. - * - * @memberof Globe.prototype - * - * @type {Boolean} - * @default false - * - * @see Globe#frontFaceAlpha - * @see Globe#frontFaceAlphaByDistance - * @see Globe#backFaceAlpha - * @see Globe#backFaceAlphaByDistance - */ - translucencyEnabled: { - get: function () { - return this._translucencyEnabled; - }, - set: function (value) { - //>>includeStart('debug', pragmas.debug); - Check.typeOf.bool("translucencyEnabled", value); - //>>includeEnd('debug'); - this._translucencyEnabled = value; - }, - }, - - /** - * A constant translucency to apply to front faces of the globe. - *

- * {@link Globe#translucencyEnabled} must be set to true for this option to take effect. - * - * @memberof Globe.prototype - * - * @type {Number} - * @default 1.0 - * - * @see Globe#translucencyEnabled - * @see Globe#frontFaceAlphaByDistance - * - * @example - * // Set front face translucency to 0.5. - * globe.frontFaceAlpha = 0.5; - * globe.translucencyEnabled = true; - */ - frontFaceAlpha: { - get: function () { - return this._frontFaceAlpha; - }, - set: function (value) { - //>>includeStart('debug', pragmas.debug); - Check.typeOf.number.greaterThanOrEquals("frontFaceAlpha", value, 0.0); - Check.typeOf.number.lessThanOrEquals("frontFaceAlpha", value, 1.0); - //>>includeEnd('debug'); - this._frontFaceAlpha = value; - }, - }, - /** - * Gets or sets near and far translucency properties of front faces of the globe based on the distance to the camera. - * The translucency will interpolate between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the translucency remains clamped to the nearest bound. If undefined, - * frontFaceAlphaByDistance will be disabled. - *

- * {@link Globe#translucencyEnabled} must be set to true for this option to take effect. - * - * @memberof Globe.prototype - * - * @type {NearFarScalar} - * @default undefined - * - * @see Globe#translucencyEnabled - * @see Globe#frontFaceAlpha - * - * @example - * // Example 1. - * // Set front face translucency to 0.5 when the - * // camera is 1500 meters from the surface and 1.0 - * // as the camera distance approaches 8.0e6 meters. - * globe.frontFaceAlphaByDistance = new Cesium.NearFarScalar(1.5e2, 0.5, 8.0e6, 1.0); - * globe.translucencyEnabled = true; - * - * @example - * // Example 2. - * // Disable front face translucency by distance - * globe.frontFaceAlphaByDistance = undefined; - */ - frontFaceAlphaByDistance: { - get: function () { - return this._frontFaceAlphaByDistance; - }, - set: function (value) { - //>>includeStart('debug', pragmas.debug); - if (defined(value) && value.far < value.near) { - throw new DeveloperError( - "far distance must be greater than near distance." - ); - } - //>>includeEnd('debug'); - this._frontFaceAlphaByDistance = NearFarScalar.clone( - value, - this._frontFaceAlphaByDistance - ); - }, - }, - - /** - * A constant translucency to apply to back faces of the globe. - *

- * {@link Globe#translucencyEnabled} must be set to true for this option to take effect. + * Properties for controlling globe translucency. * * @memberof Globe.prototype - * - * @type {Number} - * @default 1.0 - * - * @see Globe#translucencyEnabled - * @see Globe#backFaceAlphaByDistance - * - * @example - * // Set back face translucency to 0.5. - * globe.backFaceAlpha = 0.5; - * globe.translucencyEnabled = true; + * @type {GlobeTranslucency} */ - backFaceAlpha: { + translucency: { get: function () { - return this._backFaceAlpha; - }, - set: function (value) { - //>>includeStart('debug', pragmas.debug); - Check.typeOf.number.greaterThanOrEquals("backFaceAlpha", value, 0.0); - Check.typeOf.number.lessThanOrEquals("backFaceAlpha", value, 1.0); - //>>includeEnd('debug'); - this._backFaceAlpha = value; - }, - }, - /** - * Gets or sets near and far translucency properties of back faces of the globe based on the distance to the camera. - * The translucency will interpolate between the {@link NearFarScalar#nearValue} and - * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds - * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. - * Outside of these ranges the translucency remains clamped to the nearest bound. If undefined, - * backFaceAlphaByDistance will be disabled. - *

- * {@link Globe#translucencyEnabled} must be set to true for this option to take effect. - * - * @memberof Globe.prototype - * - * @type {NearFarScalar} - * @default undefined - * - * @see Globe#translucencyEnabled - * @see Globe#backFaceAlpha - * - * @example - * // Example 1. - * // Set back face translucency to 0.5 when the - * // camera is 1500 meters from the surface and 1.0 - * // as the camera distance approaches 8.0e6 meters. - * globe.backFaceAlphaByDistance = new Cesium.NearFarScalar(1.5e2, 0.5, 8.0e6, 1.0); - * globe.translucencyEnabled = true; - * - * @example - * // Example 2. - * // Disable back face translucency by distance - * globe.backFaceAlphaByDistance = undefined; - */ - backFaceAlphaByDistance: { - get: function () { - return this._backFaceAlphaByDistance; - }, - set: function (value) { - //>>includeStart('debug', pragmas.debug); - if (defined(value) && value.far < value.near) { - throw new DeveloperError( - "far distance must be greater than near distance." - ); - } - //>>includeEnd('debug'); - this._backFaceAlphaByDistance = NearFarScalar.clone( - value, - this._backFaceAlphaByDistance - ); - }, - }, - - /** - * A property specifying a {@link Rectangle} used to limit translucency to a cartographic area. - * Defaults to the maximum extent of cartographic coordinates. - * - * @member Globe.prototype - * @type {Rectangle} - * @default Rectangle.MAX_VALUE - */ - translucencyRectangle: { - get: function () { - return this._surface.tileProvider.translucencyRectangle; - }, - set: function (value) { - if (!defined(value)) { - value = Rectangle.clone(Rectangle.MAX_VALUE); - } - Rectangle.clone(value, this._surface.tileProvider.translucencyRectangle); + return this._translucency; }, }, }); diff --git a/Source/Scene/GlobeSurfaceTileProvider.js b/Source/Scene/GlobeSurfaceTileProvider.js index 19c55a099d71..3473491f5e11 100644 --- a/Source/Scene/GlobeSurfaceTileProvider.js +++ b/Source/Scene/GlobeSurfaceTileProvider.js @@ -105,7 +105,6 @@ function GlobeSurfaceTileProvider(options) { this.showSkirts = true; this.backFaceCulling = true; - this.translucencyRectangle = Rectangle.clone(Rectangle.MAX_VALUE); this.undergroundColor = undefined; this.undergroundColorAlphaByDistance = undefined; @@ -1947,6 +1946,7 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) { var frontFaceAlphaByDistance = globeTranslucencyState.frontFaceAlphaByDistance; var backFaceAlphaByDistance = globeTranslucencyState.backFaceAlphaByDistance; + var translucencyRectangle = globeTranslucencyState.rectangle; var undergroundColor = defaultValue( tileProvider.undergroundColor, @@ -2260,9 +2260,9 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) { ); var localizedTranslucencyRectangle = localizedTranslucencyRectangleScratch; - var translucencyRectangle = clipRectangleAntimeridian( + var clippedTranslucencyRectangle = clipRectangleAntimeridian( tile.rectangle, - tileProvider.translucencyRectangle + translucencyRectangle ); Cartesian3.fromElements( @@ -2294,16 +2294,16 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) { ); localizedTranslucencyRectangle.x = - (translucencyRectangle.west - cartographicTileRectangle.west) * + (clippedTranslucencyRectangle.west - cartographicTileRectangle.west) * inverseTileWidth; localizedTranslucencyRectangle.y = - (translucencyRectangle.south - cartographicTileRectangle.south) * + (clippedTranslucencyRectangle.south - cartographicTileRectangle.south) * inverseTileHeight; localizedTranslucencyRectangle.z = - (translucencyRectangle.east - cartographicTileRectangle.west) * + (clippedTranslucencyRectangle.east - cartographicTileRectangle.west) * inverseTileWidth; localizedTranslucencyRectangle.w = - (translucencyRectangle.north - cartographicTileRectangle.south) * + (clippedTranslucencyRectangle.north - cartographicTileRectangle.south) * inverseTileHeight; Cartesian4.clone( diff --git a/Source/Scene/GlobeTranslucency.js b/Source/Scene/GlobeTranslucency.js new file mode 100644 index 000000000000..69c82916de0f --- /dev/null +++ b/Source/Scene/GlobeTranslucency.js @@ -0,0 +1,238 @@ +import Check from "../Core/Check.js"; +import defined from "../Core/defined.js"; +import DeveloperError from "../Core/DeveloperError.js"; +import NearFarScalar from "../Core/NearFarScalar.js"; +import Rectangle from "../Core/Rectangle.js"; + +/** + * Properties for controlling globe translucency. + * + * @alias GlobeTranslucency + * @constructor + */ +function GlobeTranslucency() { + this._enabled = false; + this._frontFaceAlpha = 1.0; + this._frontFaceAlphaByDistance = undefined; + this._backFaceAlpha = 1.0; + this._backFaceAlphaByDistance = undefined; + this._rectangle = Rectangle.clone(Rectangle.MAX_VALUE); +} + +Object.defineProperties(GlobeTranslucency.prototype, { + /** + * When true, the globe is rendered as a translucent surface. + *

+ * The alpha is computed by blending {@link Globe#material}, {@link Globe#imageryLayers}, + * and {@link Globe#baseColor}, all of which may contain translucency, and then multiplying by + * {@link GlobeTranslucency#frontFaceAlpha} and {@link GlobeTranslucency#frontFaceAlphaByDistance} for front faces and + * {@link GlobeTranslucency#backFaceAlpha} and {@link GlobeTranslucency#backFaceAlphaByDistance} for back faces. + * When the camera is underground back faces and front faces are swapped, i.e. back-facing geometry + * is considered front facing. + *

+ * Translucency is disabled by default. + * + * @memberof GlobeTranslucency.prototype + * + * @type {Boolean} + * @default false + * + * @see GlobeTranslucency#frontFaceAlpha + * @see GlobeTranslucency#frontFaceAlphaByDistance + * @see GlobeTranslucency#backFaceAlpha + * @see GlobeTranslucency#backFaceAlphaByDistance + */ + enabled: { + get: function () { + return this._enabled; + }, + set: function (value) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.bool("enabled", value); + //>>includeEnd('debug'); + this._enabled = value; + }, + }, + + /** + * A constant translucency to apply to front faces of the globe. + *

+ * {@link GlobeTranslucency#enabled} must be set to true for this option to take effect. + * + * @memberof GlobeTranslucency.prototype + * + * @type {Number} + * @default 1.0 + * + * @see GlobeTranslucency#enabled + * @see GlobeTranslucency#frontFaceAlphaByDistance + * + * @example + * // Set front face translucency to 0.5. + * globe.translucency.frontFaceAlpha = 0.5; + * globe.translucency.enabled = true; + */ + frontFaceAlpha: { + get: function () { + return this._frontFaceAlpha; + }, + set: function (value) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.number.greaterThanOrEquals("frontFaceAlpha", value, 0.0); + Check.typeOf.number.lessThanOrEquals("frontFaceAlpha", value, 1.0); + //>>includeEnd('debug'); + this._frontFaceAlpha = value; + }, + }, + /** + * Gets or sets near and far translucency properties of front faces of the globe based on the distance to the camera. + * The translucency will interpolate between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the translucency remains clamped to the nearest bound. If undefined, + * frontFaceAlphaByDistance will be disabled. + *

+ * {@link GlobeTranslucency#enabled} must be set to true for this option to take effect. + * + * @memberof GlobeTranslucency.prototype + * + * @type {NearFarScalar} + * @default undefined + * + * @see GlobeTranslucency#enabled + * @see GlobeTranslucency#frontFaceAlpha + * + * @example + * // Example 1. + * // Set front face translucency to 0.5 when the + * // camera is 1500 meters from the surface and 1.0 + * // as the camera distance approaches 8.0e6 meters. + * globe.translucency.frontFaceAlphaByDistance = new Cesium.NearFarScalar(1.5e2, 0.5, 8.0e6, 1.0); + * globe.translucency.enabled = true; + * + * @example + * // Example 2. + * // Disable front face translucency by distance + * globe.translucency.frontFaceAlphaByDistance = undefined; + */ + frontFaceAlphaByDistance: { + get: function () { + return this._frontFaceAlphaByDistance; + }, + set: function (value) { + //>>includeStart('debug', pragmas.debug); + if (defined(value) && value.far < value.near) { + throw new DeveloperError( + "far distance must be greater than near distance." + ); + } + //>>includeEnd('debug'); + this._frontFaceAlphaByDistance = NearFarScalar.clone( + value, + this._frontFaceAlphaByDistance + ); + }, + }, + + /** + * A constant translucency to apply to back faces of the globe. + *

+ * {@link GlobeTranslucency#enabled} must be set to true for this option to take effect. + * + * @memberof GlobeTranslucency.prototype + * + * @type {Number} + * @default 1.0 + * + * @see GlobeTranslucency#enabled + * @see GlobeTranslucency#backFaceAlphaByDistance + * + * @example + * // Set back face translucency to 0.5. + * globe.translucency.backFaceAlpha = 0.5; + * globe.translucency.enabled = true; + */ + backFaceAlpha: { + get: function () { + return this._backFaceAlpha; + }, + set: function (value) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.number.greaterThanOrEquals("backFaceAlpha", value, 0.0); + Check.typeOf.number.lessThanOrEquals("backFaceAlpha", value, 1.0); + //>>includeEnd('debug'); + this._backFaceAlpha = value; + }, + }, + /** + * Gets or sets near and far translucency properties of back faces of the globe based on the distance to the camera. + * The translucency will interpolate between the {@link NearFarScalar#nearValue} and + * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds + * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}. + * Outside of these ranges the translucency remains clamped to the nearest bound. If undefined, + * backFaceAlphaByDistance will be disabled. + *

+ * {@link GlobeTranslucency#enabled} must be set to true for this option to take effect. + * + * @memberof GlobeTranslucency.prototype + * + * @type {NearFarScalar} + * @default undefined + * + * @see GlobeTranslucency#enabled + * @see GlobeTranslucency#backFaceAlpha + * + * @example + * // Example 1. + * // Set back face translucency to 0.5 when the + * // camera is 1500 meters from the surface and 1.0 + * // as the camera distance approaches 8.0e6 meters. + * globe.translucency.backFaceAlphaByDistance = new Cesium.NearFarScalar(1.5e2, 0.5, 8.0e6, 1.0); + * globe.translucency.enabled = true; + * + * @example + * // Example 2. + * // Disable back face translucency by distance + * globe.translucency.backFaceAlphaByDistance = undefined; + */ + backFaceAlphaByDistance: { + get: function () { + return this._backFaceAlphaByDistance; + }, + set: function (value) { + //>>includeStart('debug', pragmas.debug); + if (defined(value) && value.far < value.near) { + throw new DeveloperError( + "far distance must be greater than near distance." + ); + } + //>>includeEnd('debug'); + this._backFaceAlphaByDistance = NearFarScalar.clone( + value, + this._backFaceAlphaByDistance + ); + }, + }, + + /** + * A property specifying a {@link Rectangle} used to limit translucency to a cartographic area. + * Defaults to the maximum extent of cartographic coordinates. + * + * @member GlobeTranslucency.prototype + * @type {Rectangle} + * @default Rectangle.MAX_VALUE + */ + rectangle: { + get: function () { + return this._rectangle; + }, + set: function (value) { + if (!defined(value)) { + value = Rectangle.clone(Rectangle.MAX_VALUE); + } + Rectangle.clone(value, this._rectangle); + }, + }, +}); + +export default GlobeTranslucency; diff --git a/Source/Scene/GlobeTranslucencyState.js b/Source/Scene/GlobeTranslucencyState.js index 79c52661d6f4..926b572bca3b 100644 --- a/Source/Scene/GlobeTranslucencyState.js +++ b/Source/Scene/GlobeTranslucencyState.js @@ -2,6 +2,7 @@ import combine from "../Core/combine.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; import NearFarScalar from "../Core/NearFarScalar.js"; +import Rectangle from "../Core/Rectangle.js"; import DrawCommand from "../Renderer/DrawCommand.js"; import Pass from "../Renderer/Pass.js"; import RenderState from "../Renderer/RenderState.js"; @@ -57,6 +58,7 @@ function GlobeTranslucencyState() { this._useDepthPlane = false; this._numberOfTextureUniforms = 0; this._globeTranslucencyFramebuffer = undefined; + this._rectangle = Rectangle.clone(Rectangle.MAX_VALUE); this._derivedCommandKey = 0; this._derivedCommandsDirty = false; @@ -109,6 +111,11 @@ Object.defineProperties(GlobeTranslucencyState.prototype, { return this._numberOfTextureUniforms; }, }, + rectangle: { + get: function () { + return this._rectangle; + }, + }, }); /** @@ -129,15 +136,15 @@ GlobeTranslucencyState.prototype.update = function ( } this._frontFaceAlphaByDistance = updateAlphaByDistance( - globe.translucencyEnabled, - globe.frontFaceAlpha, - globe.frontFaceAlphaByDistance, + globe.translucency.enabled, + globe.translucency.frontFaceAlpha, + globe.translucency.frontFaceAlphaByDistance, this._frontFaceAlphaByDistance ); this._backFaceAlphaByDistance = updateAlphaByDistance( - globe.translucencyEnabled, - globe.backFaceAlpha, - globe.backFaceAlphaByDistance, + globe.translucency.enabled, + globe.translucency.backFaceAlpha, + globe.translucency.backFaceAlphaByDistance, this._backFaceAlphaByDistance ); @@ -162,16 +169,16 @@ GlobeTranslucencyState.prototype.update = function ( this._numberOfTextureUniforms = getNumberOfTextureUniforms(this); this._globeTranslucencyFramebuffer = globeTranslucencyFramebuffer; + this._rectangle = Rectangle.clone( + globe.translucency.rectangle, + this._rectangle + ); + gatherDerivedCommandRequirements(this, frameState); }; -function updateAlphaByDistance( - translucencyEnabled, - alpha, - alphaByDistance, - result -) { - if (!translucencyEnabled) { +function updateAlphaByDistance(enabled, alpha, alphaByDistance, result) { + if (!enabled) { result.nearValue = 1.0; result.farValue = 1.0; return result; diff --git a/Specs/Scene/GlobeTranslucencyStateSpec.js b/Specs/Scene/GlobeTranslucencyStateSpec.js index e632173f7645..29910af0d356 100644 --- a/Specs/Scene/GlobeTranslucencyStateSpec.js +++ b/Specs/Scene/GlobeTranslucencyStateSpec.js @@ -21,11 +21,11 @@ var framebuffer; function reset() { globe.show = true; - globe.translucencyEnabled = false; - globe.frontFaceAlpha = 1.0; - globe.frontFaceAlphaByDistance = undefined; - globe.backFaceAlpha = 1.0; - globe.backFaceAlphaByDistance = undefined; + globe.translucency.enabled = false; + globe.translucency.frontFaceAlpha = 1.0; + globe.translucency.frontFaceAlphaByDistance = undefined; + globe.translucency.backFaceAlpha = 1.0; + globe.translucency.backFaceAlphaByDistance = undefined; globe.baseColor = Color.WHITE; globe.depthTestAgainstTerrain = false; @@ -106,9 +106,9 @@ describe("Scene/GlobeTranslucencyState", function () { // Front and back translucent reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; - globe.backFaceAlpha = 0.25; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; + globe.translucency.backFaceAlpha = 0.25; state.update(globe, framebuffer, frameState); expect(frontFaceAlphaByDistance.nearValue).toBe(0.5); expect(frontFaceAlphaByDistance.farValue).toBe(0.5); @@ -117,10 +117,15 @@ describe("Scene/GlobeTranslucencyState", function () { // Front and back translucent with alpha by distance reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; - globe.backFaceAlpha = 0.25; - globe.frontFaceAlphaByDistance = new NearFarScalar(0.0, 0.5, 1.0, 0.75); + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; + globe.translucency.backFaceAlpha = 0.25; + globe.translucency.frontFaceAlphaByDistance = new NearFarScalar( + 0.0, + 0.5, + 1.0, + 0.75 + ); state.update(globe, framebuffer, frameState); expect(frontFaceAlphaByDistance.nearValue).toBe(0.25); expect(frontFaceAlphaByDistance.farValue).toBe(0.375); @@ -147,15 +152,15 @@ describe("Scene/GlobeTranslucencyState", function () { // Returns true when base color is translucent reset(); - globe.translucencyEnabled = true; + globe.translucency.enabled = true; globe.baseColor = Color.TRANSPARENT; state.update(globe, framebuffer, frameState); expect(state.translucent).toBe(true); // Returns true when front face alpha is less than 1.0 reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; state.update(globe, framebuffer, frameState); expect(state.translucent).toBe(true); }); @@ -179,23 +184,23 @@ describe("Scene/GlobeTranslucencyState", function () { // Returns true if front face and back face are translucent and camera is above ground reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; - globe.backFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; + globe.translucency.backFaceAlpha = 0.5; state.update(globe, framebuffer, frameState); expect(state.sunVisibleThroughGlobe).toBe(true); // Returns false if front face is translucent and back face is opaque and camera is above ground reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; state.update(globe, framebuffer, frameState); expect(state.sunVisibleThroughGlobe).toBe(false); // Returns true if front face is translucent and camera is underground reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; frameState.cameraUnderground = true; state.update(globe, framebuffer, frameState); expect(state.sunVisibleThroughGlobe).toBe(true); @@ -226,8 +231,8 @@ describe("Scene/GlobeTranslucencyState", function () { // Returns true if front faces are translucent and camera is underground reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; frameState.cameraUnderground = true; state.update(globe, framebuffer, frameState); expect(state.environmentVisible).toBe(true); @@ -253,8 +258,8 @@ describe("Scene/GlobeTranslucencyState", function () { // Return false when globe is translucent reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; state.update(globe, framebuffer, frameState); expect(state.useDepthPlane).toBe(false); }); @@ -267,15 +272,15 @@ describe("Scene/GlobeTranslucencyState", function () { // Returns two when globe is translucent and manual depth testing is required reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; state.update(globe, framebuffer, frameState); expect(state.numberOfTextureUniforms).toBe(1 + scene.context.depthTexture); // Returns one when globe is translucent and manual depth testing is not required reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; globe.depthTestAgainstTerrain = true; state.update(globe, framebuffer, frameState); expect(state.numberOfTextureUniforms).toBe(1); @@ -311,8 +316,8 @@ describe("Scene/GlobeTranslucencyState", function () { // Front translucent, back opaque reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; globe.depthTestAgainstTerrain = true; state.update(globe, framebuffer, frameState); checkTypes(state, [ @@ -324,8 +329,8 @@ describe("Scene/GlobeTranslucencyState", function () { // Front translucent, back opaque, manual depth test reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; state.update(globe, framebuffer, frameState); checkTypes(state, [ [2, 1, 7], @@ -336,8 +341,8 @@ describe("Scene/GlobeTranslucencyState", function () { // Front translucent, back opaque, manual depth test, camera underground reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; frameState.cameraUnderground = true; state.update(globe, framebuffer, frameState); checkTypes(state, [ @@ -349,9 +354,9 @@ describe("Scene/GlobeTranslucencyState", function () { // Front translucent, back translucent reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; - globe.backFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; + globe.translucency.backFaceAlpha = 0.5; state.update(globe, framebuffer, frameState); checkTypes(state, [ [4, 6, 5], @@ -362,9 +367,9 @@ describe("Scene/GlobeTranslucencyState", function () { // Front translucent, back translucent, camera underground reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; - globe.backFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; + globe.translucency.backFaceAlpha = 0.5; frameState.cameraUnderground = true; state.update(globe, framebuffer, frameState); checkTypes(state, [ @@ -376,8 +381,8 @@ describe("Scene/GlobeTranslucencyState", function () { // Translucent, 2D reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; frameState.mode = SceneMode.SCENE2D; state.update(globe, framebuffer, frameState); checkTypes(state, [ @@ -395,16 +400,16 @@ describe("Scene/GlobeTranslucencyState", function () { // Front translucent, back opaque reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; globe.depthTestAgainstTerrain = true; state.update(globe, framebuffer, frameState); expect(state._derivedCommandsDirty).toBe(true); // Same state reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; globe.depthTestAgainstTerrain = true; state.update(globe, framebuffer, frameState); expect(state._derivedCommandsDirty).toBe(false); @@ -427,8 +432,8 @@ describe("Scene/GlobeTranslucencyState", function () { var renderState = command.renderState; reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; globe.depthTestAgainstTerrain = true; state.update(globe, framebuffer, frameState); state.updateDerivedCommands(command, frameState); @@ -459,8 +464,8 @@ describe("Scene/GlobeTranslucencyState", function () { }); reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; globe.depthTestAgainstTerrain = true; state.update(globe, framebuffer, frameState); state.updateDerivedCommands(command, frameState); @@ -480,8 +485,8 @@ describe("Scene/GlobeTranslucencyState", function () { command.renderState = renderState; reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; globe.depthTestAgainstTerrain = true; state.update(globe, framebuffer, frameState); state.updateDerivedCommands(command, frameState); @@ -497,8 +502,8 @@ describe("Scene/GlobeTranslucencyState", function () { var command = createDrawCommand(); reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; frameState.passes.pick = true; state.update(globe, framebuffer, frameState); state.updateDerivedCommands(command, frameState); @@ -524,8 +529,8 @@ describe("Scene/GlobeTranslucencyState", function () { // isBlendCommand = false reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; globe.depthTestAgainstTerrain = true; state.update(globe, framebuffer, frameState); state.updateDerivedCommands(command, frameState); @@ -540,8 +545,8 @@ describe("Scene/GlobeTranslucencyState", function () { // isBlendCommand = true reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; globe.depthTestAgainstTerrain = true; state.update(globe, framebuffer, frameState); state.updateDerivedCommands(command, frameState); @@ -554,8 +559,8 @@ describe("Scene/GlobeTranslucencyState", function () { // picking reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; globe.depthTestAgainstTerrain = true; frameState.passes.pick = true; state.update(globe, framebuffer, frameState); @@ -578,8 +583,8 @@ describe("Scene/GlobeTranslucencyState", function () { spyOn(GlobeTranslucencyFramebuffer.prototype, "clearClassification"); reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; globe.depthTestAgainstTerrain = true; state.update(globe, framebuffer, frameState); state.updateDerivedCommands(command, frameState); @@ -637,8 +642,8 @@ describe("Scene/GlobeTranslucencyState", function () { spyOn(GlobeTranslucencyFramebuffer.prototype, "clearClassification"); reset(); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; globe.depthTestAgainstTerrain = true; state.update(globe, framebuffer, frameState); state.updateDerivedCommands(command, frameState); diff --git a/Specs/Scene/SceneSpec.js b/Specs/Scene/SceneSpec.js index b7c65d5c3dc1..ab1a2a989115 100644 --- a/Specs/Scene/SceneSpec.js +++ b/Specs/Scene/SceneSpec.js @@ -2209,8 +2209,8 @@ describe( scene.renderForSpecs(); expect(getFrustumCommandsLength(scene, Pass.OPAQUE)).toBe(0); - scene.globe.translucencyEnabled = true; - scene.globe.frontFaceAlpha = 0.5; + scene.globe.translucency.enabled = true; + scene.globe.translucency.frontFaceAlpha = 0.5; scene.renderForSpecs(); expect(getFrustumCommandsLength(scene, Pass.OPAQUE)).toBe(1); @@ -2242,12 +2242,12 @@ describe( var time = JulianDate.fromIso8601( "2020-04-25T03:07:26.04924034334544558Z" ); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; scene.renderForSpecs(time); expect(scene.environmentState.isSunVisible).toBe(true); - globe.translucencyEnabled = false; + globe.translucency.enabled = false; scene.renderForSpecs(time); expect(scene.environmentState.isSunVisible).toBe(false); scene.destroyForSpecs(time); @@ -2278,8 +2278,8 @@ describe( opaqueColor = rgba; }); - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; expect(scene).toRenderAndCall(function (rgba) { expect(rgba).not.toEqual(opaqueColor); @@ -2292,8 +2292,8 @@ describe( var globe = new Globe(); scene.globe = globe; globe.baseColor = Color.BLACK; - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; scene.camera.setView({ destination: new Cartesian3( @@ -2342,8 +2342,8 @@ describe( var globe = new Globe(); scene.globe = globe; globe.baseColor = Color.BLACK; - globe.translucencyEnabled = true; - globe.frontFaceAlpha = 0.5; + globe.translucency.enabled = true; + globe.translucency.frontFaceAlpha = 0.5; scene.camera.setView({ destination: new Cartesian3(