123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- import Cartesian3 from '../Core/Cartesian3.js';
- import Cartesian4 from '../Core/Cartesian4.js';
- import defaultValue from '../Core/defaultValue.js';
- import defined from '../Core/defined.js';
- import defineProperties from '../Core/defineProperties.js';
- import destroyObject from '../Core/destroyObject.js';
- import Ellipsoid from '../Core/Ellipsoid.js';
- import EllipsoidGeometry from '../Core/EllipsoidGeometry.js';
- import GeometryPipeline from '../Core/GeometryPipeline.js';
- import CesiumMath from '../Core/Math.js';
- import VertexFormat from '../Core/VertexFormat.js';
- import BufferUsage from '../Renderer/BufferUsage.js';
- import DrawCommand from '../Renderer/DrawCommand.js';
- import RenderState from '../Renderer/RenderState.js';
- import ShaderProgram from '../Renderer/ShaderProgram.js';
- import ShaderSource from '../Renderer/ShaderSource.js';
- import VertexArray from '../Renderer/VertexArray.js';
- import SkyAtmosphereFS from '../Shaders/SkyAtmosphereFS.js';
- import SkyAtmosphereVS from '../Shaders/SkyAtmosphereVS.js';
- import BlendingState from './BlendingState.js';
- import CullFace from './CullFace.js';
- import SceneMode from './SceneMode.js';
- /**
- * An atmosphere drawn around the limb of the provided ellipsoid. Based on
- * {@link https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter16.html|Accurate Atmospheric Scattering}
- * in GPU Gems 2.
- * <p>
- * This is only supported in 3D. Atmosphere is faded out when morphing to 2D or Columbus view.
- * </p>
- *
- * @alias SkyAtmosphere
- * @constructor
- *
- * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid that the atmosphere is drawn around.
- *
- * @example
- * scene.skyAtmosphere = new Cesium.SkyAtmosphere();
- *
- * @demo {@link https://sandcastle.cesium.com/index.html?src=Sky%20Atmosphere.html|Sky atmosphere demo in Sandcastle}
- *
- * @see Scene.skyAtmosphere
- */
- function SkyAtmosphere(ellipsoid) {
- ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84);
- /**
- * Determines if the atmosphere is shown.
- *
- * @type {Boolean}
- * @default true
- */
- this.show = true;
- this._ellipsoid = ellipsoid;
- this._command = new DrawCommand({
- owner : this
- });
- this._spSkyFromSpace = undefined;
- this._spSkyFromAtmosphere = undefined;
- this._spSkyFromSpaceColorCorrect = undefined;
- this._spSkyFromAtmosphereColorCorrect = undefined;
- /**
- * The hue shift to apply to the atmosphere. Defaults to 0.0 (no shift).
- * A hue shift of 1.0 indicates a complete rotation of the hues available.
- * @type {Number}
- * @default 0.0
- */
- this.hueShift = 0.0;
- /**
- * The saturation shift to apply to the atmosphere. Defaults to 0.0 (no shift).
- * A saturation shift of -1.0 is monochrome.
- * @type {Number}
- * @default 0.0
- */
- this.saturationShift = 0.0;
- /**
- * The brightness shift to apply to the atmosphere. Defaults to 0.0 (no shift).
- * A brightness shift of -1.0 is complete darkness, which will let space show through.
- * @type {Number}
- * @default 0.0
- */
- this.brightnessShift = 0.0;
- this._hueSaturationBrightness = new Cartesian3();
- // camera height, outer radius, inner radius, dynamic atmosphere color flag
- var cameraAndRadiiAndDynamicAtmosphereColor = new Cartesian4();
- // Toggles whether the sun position is used. 0 treats the sun as always directly overhead.
- cameraAndRadiiAndDynamicAtmosphereColor.w = 0;
- cameraAndRadiiAndDynamicAtmosphereColor.y = Cartesian3.maximumComponent(Cartesian3.multiplyByScalar(ellipsoid.radii, 1.025, new Cartesian3()));
- cameraAndRadiiAndDynamicAtmosphereColor.z = ellipsoid.maximumRadius;
- this._cameraAndRadiiAndDynamicAtmosphereColor = cameraAndRadiiAndDynamicAtmosphereColor;
- var that = this;
- this._command.uniformMap = {
- u_cameraAndRadiiAndDynamicAtmosphereColor : function() {
- return that._cameraAndRadiiAndDynamicAtmosphereColor;
- },
- u_hsbShift : function() {
- that._hueSaturationBrightness.x = that.hueShift;
- that._hueSaturationBrightness.y = that.saturationShift;
- that._hueSaturationBrightness.z = that.brightnessShift;
- return that._hueSaturationBrightness;
- }
- };
- }
- defineProperties(SkyAtmosphere.prototype, {
- /**
- * Gets the ellipsoid the atmosphere is drawn around.
- * @memberof SkyAtmosphere.prototype
- *
- * @type {Ellipsoid}
- * @readonly
- */
- ellipsoid : {
- get : function() {
- return this._ellipsoid;
- }
- }
- });
- /**
- * @private
- */
- SkyAtmosphere.prototype.setDynamicAtmosphereColor = function(enableLighting) {
- this._cameraAndRadiiAndDynamicAtmosphereColor.w = enableLighting ? 1 : 0;
- };
- /**
- * @private
- */
- SkyAtmosphere.prototype.update = function(frameState) {
- if (!this.show) {
- return undefined;
- }
- var mode = frameState.mode;
- if ((mode !== SceneMode.SCENE3D) &&
- (mode !== SceneMode.MORPHING)) {
- return undefined;
- }
- // The atmosphere is only rendered during the render pass; it is not pickable, it doesn't cast shadows, etc.
- if (!frameState.passes.render) {
- return undefined;
- }
- var command = this._command;
- if (!defined(command.vertexArray)) {
- var context = frameState.context;
- var geometry = EllipsoidGeometry.createGeometry(new EllipsoidGeometry({
- radii : Cartesian3.multiplyByScalar(this._ellipsoid.radii, 1.025, new Cartesian3()),
- slicePartitions : 256,
- stackPartitions : 256,
- vertexFormat : VertexFormat.POSITION_ONLY
- }));
- command.vertexArray = VertexArray.fromGeometry({
- context : context,
- geometry : geometry,
- attributeLocations : GeometryPipeline.createAttributeLocations(geometry),
- bufferUsage : BufferUsage.STATIC_DRAW
- });
- command.renderState = RenderState.fromCache({
- cull : {
- enabled : true,
- face : CullFace.FRONT
- },
- blending : BlendingState.ALPHA_BLEND,
- depthMask : false
- });
- var vs = new ShaderSource({
- defines : ['SKY_FROM_SPACE'],
- sources : [SkyAtmosphereVS]
- });
- this._spSkyFromSpace = ShaderProgram.fromCache({
- context : context,
- vertexShaderSource : vs,
- fragmentShaderSource : SkyAtmosphereFS
- });
- vs = new ShaderSource({
- defines : ['SKY_FROM_ATMOSPHERE'],
- sources : [SkyAtmosphereVS]
- });
- this._spSkyFromAtmosphere = ShaderProgram.fromCache({
- context : context,
- vertexShaderSource : vs,
- fragmentShaderSource : SkyAtmosphereFS
- });
- }
- // Compile the color correcting versions of the shader on demand
- var useColorCorrect = colorCorrect(this);
- if (useColorCorrect && (!defined(this._spSkyFromSpaceColorCorrect) || !defined(this._spSkyFromAtmosphereColorCorrect))) {
- var contextColorCorrect = frameState.context;
- var vsColorCorrect = new ShaderSource({
- defines : ['SKY_FROM_SPACE'],
- sources : [SkyAtmosphereVS]
- });
- var fsColorCorrect = new ShaderSource({
- defines : ['COLOR_CORRECT'],
- sources : [SkyAtmosphereFS]
- });
- this._spSkyFromSpaceColorCorrect = ShaderProgram.fromCache({
- context : contextColorCorrect,
- vertexShaderSource : vsColorCorrect,
- fragmentShaderSource : fsColorCorrect
- });
- vsColorCorrect = new ShaderSource({
- defines : ['SKY_FROM_ATMOSPHERE'],
- sources : [SkyAtmosphereVS]
- });
- this._spSkyFromAtmosphereColorCorrect = ShaderProgram.fromCache({
- context : contextColorCorrect,
- vertexShaderSource : vsColorCorrect,
- fragmentShaderSource : fsColorCorrect
- });
- }
- var cameraPosition = frameState.camera.positionWC;
- var cameraHeight = Cartesian3.magnitude(cameraPosition);
- this._cameraAndRadiiAndDynamicAtmosphereColor.x = cameraHeight;
- if (cameraHeight > this._cameraAndRadiiAndDynamicAtmosphereColor.y) {
- // Camera in space
- command.shaderProgram = useColorCorrect ? this._spSkyFromSpaceColorCorrect : this._spSkyFromSpace;
- } else {
- // Camera in atmosphere
- command.shaderProgram = useColorCorrect ? this._spSkyFromAtmosphereColorCorrect : this._spSkyFromAtmosphere;
- }
- return command;
- };
- function colorCorrect(skyAtmosphere) {
- return !(CesiumMath.equalsEpsilon(skyAtmosphere.hueShift, 0.0, CesiumMath.EPSILON7) &&
- CesiumMath.equalsEpsilon(skyAtmosphere.saturationShift, 0.0, CesiumMath.EPSILON7) &&
- CesiumMath.equalsEpsilon(skyAtmosphere.brightnessShift, 0.0, CesiumMath.EPSILON7));
- }
- /**
- * Returns true if this object was destroyed; otherwise, false.
- * <br /><br />
- * If this object was destroyed, it should not be used; calling any function other than
- * <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
- *
- * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>.
- *
- * @see SkyAtmosphere#destroy
- */
- SkyAtmosphere.prototype.isDestroyed = function() {
- return false;
- };
- /**
- * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic
- * release of WebGL resources, instead of relying on the garbage collector to destroy this object.
- * <br /><br />
- * Once an object is destroyed, it should not be used; calling any function other than
- * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore,
- * assign the return value (<code>undefined</code>) to the object as done in the example.
- *
- * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
- *
- *
- * @example
- * skyAtmosphere = skyAtmosphere && skyAtmosphere.destroy();
- *
- * @see SkyAtmosphere#isDestroyed
- */
- SkyAtmosphere.prototype.destroy = function() {
- var command = this._command;
- command.vertexArray = command.vertexArray && command.vertexArray.destroy();
- this._spSkyFromSpace = this._spSkyFromSpace && this._spSkyFromSpace.destroy();
- this._spSkyFromAtmosphere = this._spSkyFromAtmosphere && this._spSkyFromAtmosphere.destroy();
- this._spSkyFromSpaceColorCorrect = this._spSkyFromSpaceColorCorrect && this._spSkyFromSpaceColorCorrect.destroy();
- this._spSkyFromAtmosphereColorCorrect = this._spSkyFromAtmosphereColorCorrect && this._spSkyFromAtmosphereColorCorrect.destroy();
- return destroyObject(this);
- };
- export default SkyAtmosphere;
|