@cesium/engine
Version:
CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.
1,852 lines (1,641 loc) • 52.4 kB
JavaScript
import BoundingRectangle from "../Core/BoundingRectangle.js";
import Cartesian2 from "../Core/Cartesian2.js";
import Cartesian3 from "../Core/Cartesian3.js";
import Cartesian4 from "../Core/Cartesian4.js";
import Cartographic from "../Core/Cartographic.js";
import Color from "../Core/Color.js";
import defined from "../Core/defined.js";
import Ellipsoid from "../Core/Ellipsoid.js";
import EncodedCartesian3 from "../Core/EncodedCartesian3.js";
import CesiumMath from "../Core/Math.js";
import Matrix3 from "../Core/Matrix3.js";
import Matrix4 from "../Core/Matrix4.js";
import OrthographicFrustum from "../Core/OrthographicFrustum.js";
import Simon1994PlanetaryPositions from "../Core/Simon1994PlanetaryPositions.js";
import Transforms from "../Core/Transforms.js";
import SceneMode from "../Scene/SceneMode.js";
import SunLight from "../Scene/SunLight.js";
/**
* @private
* @constructor
*/
function UniformState() {
/**
* @type {Texture}
*/
this.globeDepthTexture = undefined;
/**
* @type {number}
*/
this.gamma = undefined;
this._viewport = new BoundingRectangle();
this._viewportCartesian4 = new Cartesian4();
this._viewportDirty = false;
this._viewportOrthographicMatrix = Matrix4.clone(Matrix4.IDENTITY);
this._viewportTransformation = Matrix4.clone(Matrix4.IDENTITY);
this._model = Matrix4.clone(Matrix4.IDENTITY);
this._view = Matrix4.clone(Matrix4.IDENTITY);
this._inverseView = Matrix4.clone(Matrix4.IDENTITY);
this._projection = Matrix4.clone(Matrix4.IDENTITY);
this._infiniteProjection = Matrix4.clone(Matrix4.IDENTITY);
this._entireFrustum = new Cartesian2();
this._currentFrustum = new Cartesian2();
this._frustumPlanes = new Cartesian4();
this._farDepthFromNearPlusOne = undefined;
this._log2FarDepthFromNearPlusOne = undefined;
this._oneOverLog2FarDepthFromNearPlusOne = undefined;
this._frameState = undefined;
this._temeToPseudoFixed = Matrix3.clone(Matrix4.IDENTITY);
// Derived members
this._view3DDirty = true;
this._view3D = new Matrix4();
this._inverseView3DDirty = true;
this._inverseView3D = new Matrix4();
this._inverseModelDirty = true;
this._inverseModel = new Matrix4();
this._inverseTransposeModelDirty = true;
this._inverseTransposeModel = new Matrix3();
this._viewRotation = new Matrix3();
this._inverseViewRotation = new Matrix3();
this._viewRotation3D = new Matrix3();
this._inverseViewRotation3D = new Matrix3();
this._inverseProjectionDirty = true;
this._inverseProjection = new Matrix4();
this._modelViewDirty = true;
this._modelView = new Matrix4();
this._modelView3DDirty = true;
this._modelView3D = new Matrix4();
this._modelViewRelativeToEyeDirty = true;
this._modelViewRelativeToEye = new Matrix4();
this._inverseModelViewDirty = true;
this._inverseModelView = new Matrix4();
this._inverseModelView3DDirty = true;
this._inverseModelView3D = new Matrix4();
this._viewProjectionDirty = true;
this._viewProjection = new Matrix4();
this._inverseViewProjectionDirty = true;
this._inverseViewProjection = new Matrix4();
this._modelViewProjectionDirty = true;
this._modelViewProjection = new Matrix4();
this._inverseModelViewProjectionDirty = true;
this._inverseModelViewProjection = new Matrix4();
this._modelViewProjectionRelativeToEyeDirty = true;
this._modelViewProjectionRelativeToEye = new Matrix4();
this._modelViewInfiniteProjectionDirty = true;
this._modelViewInfiniteProjection = new Matrix4();
this._normalDirty = true;
this._normal = new Matrix3();
this._normal3DDirty = true;
this._normal3D = new Matrix3();
this._inverseNormalDirty = true;
this._inverseNormal = new Matrix3();
this._inverseNormal3DDirty = true;
this._inverseNormal3D = new Matrix3();
this._encodedCameraPositionMCDirty = true;
this._encodedCameraPositionMC = new EncodedCartesian3();
this._cameraPosition = new Cartesian3();
this._sunPositionWC = new Cartesian3();
this._sunPositionColumbusView = new Cartesian3();
this._sunDirectionWC = new Cartesian3();
this._sunDirectionEC = new Cartesian3();
this._moonDirectionEC = new Cartesian3();
this._lightDirectionWC = new Cartesian3();
this._lightDirectionEC = new Cartesian3();
this._lightColor = new Cartesian3();
this._lightColorHdr = new Cartesian3();
this._pass = undefined;
this._mode = undefined;
this._mapProjection = undefined;
this._ellipsoid = undefined;
this._cameraDirection = new Cartesian3();
this._cameraRight = new Cartesian3();
this._cameraUp = new Cartesian3();
this._frustum2DWidth = 0.0;
this._eyeHeight = 0.0;
this._eyeHeight2D = new Cartesian2();
this._eyeEllipsoidNormalEC = new Cartesian3();
this._eyeEllipsoidCurvature = new Cartesian2();
this._modelToEnu = new Matrix4();
this._enuToModel = new Matrix4();
this._pixelRatio = 1.0;
this._orthographicIn3D = false;
this._backgroundColor = new Color();
this._brdfLut = undefined;
this._environmentMap = undefined;
this._sphericalHarmonicCoefficients = undefined;
this._specularEnvironmentMaps = undefined;
this._specularEnvironmentMapsMaximumLOD = undefined;
this._fogDensity = undefined;
this._fogVisualDensityScalar = undefined;
this._fogMinimumBrightness = undefined;
this._atmosphereHsbShift = undefined;
this._atmosphereLightIntensity = undefined;
this._atmosphereRayleighCoefficient = new Cartesian3();
this._atmosphereRayleighScaleHeight = new Cartesian3();
this._atmosphereMieCoefficient = new Cartesian3();
this._atmosphereMieScaleHeight = undefined;
this._atmosphereMieAnisotropy = undefined;
this._atmosphereDynamicLighting = undefined;
this._invertClassificationColor = undefined;
this._splitPosition = 0.0;
this._pixelSizePerMeter = undefined;
this._geometricToleranceOverMeter = undefined;
this._minimumDisableDepthTestDistance = undefined;
}
Object.defineProperties(UniformState.prototype, {
/**
* @memberof UniformState.prototype
* @type {FrameState}
* @readonly
*/
frameState: {
get: function () {
return this._frameState;
},
},
/**
* @memberof UniformState.prototype
* @type {BoundingRectangle}
*/
viewport: {
get: function () {
return this._viewport;
},
set: function (viewport) {
if (!BoundingRectangle.equals(viewport, this._viewport)) {
BoundingRectangle.clone(viewport, this._viewport);
const v = this._viewport;
const vc = this._viewportCartesian4;
vc.x = v.x;
vc.y = v.y;
vc.z = v.width;
vc.w = v.height;
this._viewportDirty = true;
}
},
},
/**
* @memberof UniformState.prototype
* @private
*/
viewportCartesian4: {
get: function () {
return this._viewportCartesian4;
},
},
viewportOrthographic: {
get: function () {
cleanViewport(this);
return this._viewportOrthographicMatrix;
},
},
viewportTransformation: {
get: function () {
cleanViewport(this);
return this._viewportTransformation;
},
},
/**
* @memberof UniformState.prototype
* @type {Matrix4}
*/
model: {
get: function () {
return this._model;
},
set: function (matrix) {
Matrix4.clone(matrix, this._model);
this._modelView3DDirty = true;
this._inverseModelView3DDirty = true;
this._inverseModelDirty = true;
this._inverseTransposeModelDirty = true;
this._modelViewDirty = true;
this._inverseModelViewDirty = true;
this._modelViewRelativeToEyeDirty = true;
this._inverseModelViewDirty = true;
this._modelViewProjectionDirty = true;
this._inverseModelViewProjectionDirty = true;
this._modelViewProjectionRelativeToEyeDirty = true;
this._modelViewInfiniteProjectionDirty = true;
this._normalDirty = true;
this._inverseNormalDirty = true;
this._normal3DDirty = true;
this._inverseNormal3DDirty = true;
this._encodedCameraPositionMCDirty = true;
},
},
/**
* @memberof UniformState.prototype
* @type {Matrix4}
*/
inverseModel: {
get: function () {
if (this._inverseModelDirty) {
this._inverseModelDirty = false;
Matrix4.inverse(this._model, this._inverseModel);
}
return this._inverseModel;
},
},
/**
* @memberof UniformState.prototype
* @private
*/
inverseTransposeModel: {
get: function () {
const m = this._inverseTransposeModel;
if (this._inverseTransposeModelDirty) {
this._inverseTransposeModelDirty = false;
Matrix4.getMatrix3(this.inverseModel, m);
Matrix3.transpose(m, m);
}
return m;
},
},
/**
* @memberof UniformState.prototype
* @type {Matrix4}
*/
view: {
get: function () {
return this._view;
},
},
/**
* The 3D view matrix. In 3D mode, this is identical to {@link UniformState#view},
* but in 2D and Columbus View it is a synthetic matrix based on the equivalent position
* of the camera in the 3D world.
* @memberof UniformState.prototype
* @type {Matrix4}
*/
view3D: {
get: function () {
updateView3D(this);
return this._view3D;
},
},
/**
* The 3x3 rotation matrix of the current view matrix ({@link UniformState#view}).
* @memberof UniformState.prototype
* @type {Matrix3}
*/
viewRotation: {
get: function () {
updateView3D(this);
return this._viewRotation;
},
},
/**
* @memberof UniformState.prototype
* @type {Matrix3}
*/
viewRotation3D: {
get: function () {
updateView3D(this);
return this._viewRotation3D;
},
},
/**
* @memberof UniformState.prototype
* @type {Matrix4}
*/
inverseView: {
get: function () {
return this._inverseView;
},
},
/**
* the 4x4 inverse-view matrix that transforms from eye to 3D world coordinates. In 3D mode, this is
* identical to {@link UniformState#inverseView}, but in 2D and Columbus View it is a synthetic matrix
* based on the equivalent position of the camera in the 3D world.
* @memberof UniformState.prototype
* @type {Matrix4}
*/
inverseView3D: {
get: function () {
updateInverseView3D(this);
return this._inverseView3D;
},
},
/**
* @memberof UniformState.prototype
* @type {Matrix3}
*/
inverseViewRotation: {
get: function () {
return this._inverseViewRotation;
},
},
/**
* The 3x3 rotation matrix of the current 3D inverse-view matrix ({@link UniformState#inverseView3D}).
* @memberof UniformState.prototype
* @type {Matrix3}
*/
inverseViewRotation3D: {
get: function () {
updateInverseView3D(this);
return this._inverseViewRotation3D;
},
},
/**
* @memberof UniformState.prototype
* @type {Matrix4}
*/
projection: {
get: function () {
return this._projection;
},
},
/**
* @memberof UniformState.prototype
* @type {Matrix4}
*/
inverseProjection: {
get: function () {
cleanInverseProjection(this);
return this._inverseProjection;
},
},
/**
* @memberof UniformState.prototype
* @type {Matrix4}
*/
infiniteProjection: {
get: function () {
return this._infiniteProjection;
},
},
/**
* @memberof UniformState.prototype
* @type {Matrix4}
*/
modelView: {
get: function () {
cleanModelView(this);
return this._modelView;
},
},
/**
* The 3D model-view matrix. In 3D mode, this is equivalent to {@link UniformState#modelView}. In 2D and
* Columbus View, however, it is a synthetic matrix based on the equivalent position of the camera in the 3D world.
* @memberof UniformState.prototype
* @type {Matrix4}
*/
modelView3D: {
get: function () {
cleanModelView3D(this);
return this._modelView3D;
},
},
/**
* Model-view relative to eye matrix.
*
* @memberof UniformState.prototype
* @type {Matrix4}
*/
modelViewRelativeToEye: {
get: function () {
cleanModelViewRelativeToEye(this);
return this._modelViewRelativeToEye;
},
},
/**
* @memberof UniformState.prototype
* @type {Matrix4}
*/
inverseModelView: {
get: function () {
cleanInverseModelView(this);
return this._inverseModelView;
},
},
/**
* The inverse of the 3D model-view matrix. In 3D mode, this is equivalent to {@link UniformState#inverseModelView}.
* In 2D and Columbus View, however, it is a synthetic matrix based on the equivalent position of the camera in the 3D world.
* @memberof UniformState.prototype
* @type {Matrix4}
*/
inverseModelView3D: {
get: function () {
cleanInverseModelView3D(this);
return this._inverseModelView3D;
},
},
/**
* @memberof UniformState.prototype
* @type {Matrix4}
*/
viewProjection: {
get: function () {
cleanViewProjection(this);
return this._viewProjection;
},
},
/**
* @memberof UniformState.prototype
* @type {Matrix4}
*/
inverseViewProjection: {
get: function () {
cleanInverseViewProjection(this);
return this._inverseViewProjection;
},
},
/**
* @memberof UniformState.prototype
* @type {Matrix4}
*/
modelViewProjection: {
get: function () {
cleanModelViewProjection(this);
return this._modelViewProjection;
},
},
/**
* @memberof UniformState.prototype
* @type {Matrix4}
*/
inverseModelViewProjection: {
get: function () {
cleanInverseModelViewProjection(this);
return this._inverseModelViewProjection;
},
},
/**
* Model-view-projection relative to eye matrix.
*
* @memberof UniformState.prototype
* @type {Matrix4}
*/
modelViewProjectionRelativeToEye: {
get: function () {
cleanModelViewProjectionRelativeToEye(this);
return this._modelViewProjectionRelativeToEye;
},
},
/**
* @memberof UniformState.prototype
* @type {Matrix4}
*/
modelViewInfiniteProjection: {
get: function () {
cleanModelViewInfiniteProjection(this);
return this._modelViewInfiniteProjection;
},
},
/**
* A 3x3 normal transformation matrix that transforms normal vectors in model coordinates to
* eye coordinates.
* @memberof UniformState.prototype
* @type {Matrix3}
*/
normal: {
get: function () {
cleanNormal(this);
return this._normal;
},
},
/**
* A 3x3 normal transformation matrix that transforms normal vectors in 3D model
* coordinates to eye coordinates. In 3D mode, this is identical to
* {@link UniformState#normal}, but in 2D and Columbus View it represents the normal transformation
* matrix as if the camera were at an equivalent location in 3D mode.
* @memberof UniformState.prototype
* @type {Matrix3}
*/
normal3D: {
get: function () {
cleanNormal3D(this);
return this._normal3D;
},
},
/**
* An inverse 3x3 normal transformation matrix that transforms normal vectors in model coordinates
* to eye coordinates.
* @memberof UniformState.prototype
* @type {Matrix3}
*/
inverseNormal: {
get: function () {
cleanInverseNormal(this);
return this._inverseNormal;
},
},
/**
* An inverse 3x3 normal transformation matrix that transforms normal vectors in eye coordinates
* to 3D model coordinates. In 3D mode, this is identical to
* {@link UniformState#inverseNormal}, but in 2D and Columbus View it represents the normal transformation
* matrix as if the camera were at an equivalent location in 3D mode.
* @memberof UniformState.prototype
* @type {Matrix3}
*/
inverseNormal3D: {
get: function () {
cleanInverseNormal3D(this);
return this._inverseNormal3D;
},
},
/**
* The near distance (<code>x</code>) and the far distance (<code>y</code>) of the frustum defined by the camera.
* This is the largest possible frustum, not an individual frustum used for multi-frustum rendering.
* @memberof UniformState.prototype
* @type {Cartesian2}
*/
entireFrustum: {
get: function () {
return this._entireFrustum;
},
},
/**
* The near distance (<code>x</code>) and the far distance (<code>y</code>) of the frustum defined by the camera.
* This is the individual frustum used for multi-frustum rendering.
* @memberof UniformState.prototype
* @type {Cartesian2}
*/
currentFrustum: {
get: function () {
return this._currentFrustum;
},
},
/**
* The distances to the frustum planes. The top, bottom, left and right distances are
* the x, y, z, and w components, respectively.
* @memberof UniformState.prototype
* @type {Cartesian4}
*/
frustumPlanes: {
get: function () {
return this._frustumPlanes;
},
},
/**
* The far plane's distance from the near plane, plus 1.0.
*
* @memberof UniformState.prototype
* @type {number}
*/
farDepthFromNearPlusOne: {
get: function () {
return this._farDepthFromNearPlusOne;
},
},
/**
* The log2 of {@link UniformState#farDepthFromNearPlusOne}.
*
* @memberof UniformState.prototype
* @type {number}
*/
log2FarDepthFromNearPlusOne: {
get: function () {
return this._log2FarDepthFromNearPlusOne;
},
},
/**
* 1.0 divided by {@link UniformState#log2FarDepthFromNearPlusOne}.
*
* @memberof UniformState.prototype
* @type {number}
*/
oneOverLog2FarDepthFromNearPlusOne: {
get: function () {
return this._oneOverLog2FarDepthFromNearPlusOne;
},
},
/**
* The height in meters of the eye (camera) above or below the ellipsoid.
* @memberof UniformState.prototype
* @type {number}
*/
eyeHeight: {
get: function () {
return this._eyeHeight;
},
},
/**
* The height (<code>x</code>) and the height squared (<code>y</code>)
* in meters of the eye (camera) above the 2D world plane. This uniform is only valid
* when the {@link SceneMode} is <code>SCENE2D</code>.
* @memberof UniformState.prototype
* @type {Cartesian2}
*/
eyeHeight2D: {
get: function () {
return this._eyeHeight2D;
},
},
/**
* The ellipsoid surface normal at the camera position, in model coordinates.
* @memberof UniformState.prototype
* @type {Cartesian3}
*/
eyeEllipsoidNormalEC: {
get: function () {
return this._eyeEllipsoidNormalEC;
},
},
/**
* The ellipsoid radii of curvature at the camera position.
* The .x component is the prime vertical radius, .y is the meridional.
* @memberof UniformState.prototype
* @type {Cartesian2}
*/
eyeEllipsoidCurvature: {
get: function () {
return this._eyeEllipsoidCurvature;
},
},
/**
* A transform from model coordinates to an east-north-up coordinate system
* centered at the position on the ellipsoid below the camera
* @memberof UniformState.prototype
* @type {Matrix4}
*/
modelToEnu: {
get: function () {
return this._modelToEnu;
},
},
/**
* The inverse of {@link UniformState.prototype.modelToEnu}
* @memberof UniformState.prototype
* @type {Matrix4}
*/
enuToModel: {
get: function () {
return this._enuToModel;
},
},
/**
* The sun position in 3D world coordinates at the current scene time.
* @memberof UniformState.prototype
* @type {Cartesian3}
*/
sunPositionWC: {
get: function () {
return this._sunPositionWC;
},
},
/**
* The sun position in 2D world coordinates at the current scene time.
* @memberof UniformState.prototype
* @type {Cartesian3}
*/
sunPositionColumbusView: {
get: function () {
return this._sunPositionColumbusView;
},
},
/**
* A normalized vector to the sun in 3D world coordinates at the current scene time. Even in 2D or
* Columbus View mode, this returns the direction to the sun in the 3D scene.
* @memberof UniformState.prototype
* @type {Cartesian3}
*/
sunDirectionWC: {
get: function () {
return this._sunDirectionWC;
},
},
/**
* A normalized vector to the sun in eye coordinates at the current scene time. In 3D mode, this
* returns the actual vector from the camera position to the sun position. In 2D and Columbus View, it returns
* the vector from the equivalent 3D camera position to the position of the sun in the 3D scene.
* @memberof UniformState.prototype
* @type {Cartesian3}
*/
sunDirectionEC: {
get: function () {
return this._sunDirectionEC;
},
},
/**
* A normalized vector to the moon in eye coordinates at the current scene time. In 3D mode, this
* returns the actual vector from the camera position to the moon position. In 2D and Columbus View, it returns
* the vector from the equivalent 3D camera position to the position of the moon in the 3D scene.
* @memberof UniformState.prototype
* @type {Cartesian3}
*/
moonDirectionEC: {
get: function () {
return this._moonDirectionEC;
},
},
/**
* A normalized vector to the scene's light source in 3D world coordinates. Even in 2D or
* Columbus View mode, this returns the direction to the light in the 3D scene.
* @memberof UniformState.prototype
* @type {Cartesian3}
*/
lightDirectionWC: {
get: function () {
return this._lightDirectionWC;
},
},
/**
* A normalized vector to the scene's light source in eye coordinates. In 3D mode, this
* returns the actual vector from the camera position to the light. In 2D and Columbus View, it returns
* the vector from the equivalent 3D camera position in the 3D scene.
* @memberof UniformState.prototype
* @type {Cartesian3}
*/
lightDirectionEC: {
get: function () {
return this._lightDirectionEC;
},
},
/**
* The color of light emitted by the scene's light source. This is equivalent to the light
* color multiplied by the light intensity limited to a maximum luminance of 1.0 suitable
* for non-HDR lighting.
* @memberof UniformState.prototype
* @type {Cartesian3}
*/
lightColor: {
get: function () {
return this._lightColor;
},
},
/**
* The high dynamic range color of light emitted by the scene's light source. This is equivalent to
* the light color multiplied by the light intensity suitable for HDR lighting.
* @memberof UniformState.prototype
* @type {Cartesian3}
*/
lightColorHdr: {
get: function () {
return this._lightColorHdr;
},
},
/**
* The high bits of the camera position.
* @memberof UniformState.prototype
* @type {Cartesian3}
*/
encodedCameraPositionMCHigh: {
get: function () {
cleanEncodedCameraPositionMC(this);
return this._encodedCameraPositionMC.high;
},
},
/**
* The low bits of the camera position.
* @memberof UniformState.prototype
* @type {Cartesian3}
*/
encodedCameraPositionMCLow: {
get: function () {
cleanEncodedCameraPositionMC(this);
return this._encodedCameraPositionMC.low;
},
},
/**
* A 3x3 matrix that transforms from True Equator Mean Equinox (TEME) axes to the
* pseudo-fixed axes at the Scene's current time.
* @memberof UniformState.prototype
* @type {Matrix3}
*/
temeToPseudoFixedMatrix: {
get: function () {
return this._temeToPseudoFixed;
},
},
/**
* Gets the scaling factor for transforming from the canvas
* pixel space to canvas coordinate space.
* @memberof UniformState.prototype
* @type {number}
*/
pixelRatio: {
get: function () {
return this._pixelRatio;
},
},
/**
* A scalar used to mix a color with the fog color based on the distance to the camera.
* @memberof UniformState.prototype
* @type {number}
*/
fogDensity: {
get: function () {
return this._fogDensity;
},
},
/**
* A scalar used to mix a color with the fog color based on the distance to the camera.
* @memberof UniformState.prototype
* @type {number}
*/
fogVisualDensityScalar: {
get: function () {
return this._fogVisualDensityScalar;
},
},
/**
* A scalar used as a minimum value when brightening fog
* @memberof UniformState.prototype
* @type {number}
*/
fogMinimumBrightness: {
get: function () {
return this._fogMinimumBrightness;
},
},
/**
* A color shift to apply to the atmosphere color in HSB.
* @memberof UniformState.prototype
* @type {Cartesian3}
*/
atmosphereHsbShift: {
get: function () {
return this._atmosphereHsbShift;
},
},
/**
* The intensity of the light that is used for computing the atmosphere color
* @memberof UniformState.prototype
* @type {number}
*/
atmosphereLightIntensity: {
get: function () {
return this._atmosphereLightIntensity;
},
},
/**
* The Rayleigh scattering coefficient used in the atmospheric scattering equations for the sky atmosphere.
* @memberof UniformState.prototype
* @type {Cartesian3}
*/
atmosphereRayleighCoefficient: {
get: function () {
return this._atmosphereRayleighCoefficient;
},
},
/**
* The Rayleigh scale height used in the atmospheric scattering equations for the sky atmosphere, in meters.
* @memberof UniformState.prototype
* @type {number}
*/
atmosphereRayleighScaleHeight: {
get: function () {
return this._atmosphereRayleighScaleHeight;
},
},
/**
* The Mie scattering coefficient used in the atmospheric scattering equations for the sky atmosphere.
* @memberof UniformState.prototype
* @type {Cartesian3}
*/
atmosphereMieCoefficient: {
get: function () {
return this._atmosphereMieCoefficient;
},
},
/**
* The Mie scale height used in the atmospheric scattering equations for the sky atmosphere, in meters.
* @memberof UniformState.prototype
* @type {number}
*/
atmosphereMieScaleHeight: {
get: function () {
return this._atmosphereMieScaleHeight;
},
},
/**
* The anisotropy of the medium to consider for Mie scattering.
* @memberof UniformState.prototype
* @type {number}
*/
atmosphereMieAnisotropy: {
get: function () {
return this._atmosphereMieAnisotropy;
},
},
/**
* Which light source to use for dynamically lighting the atmosphere
*
* @memberof UniformState.prototype
* @type {DynamicAtmosphereLightingType}
*/
atmosphereDynamicLighting: {
get: function () {
return this._atmosphereDynamicLighting;
},
},
/**
* A scalar that represents the geometric tolerance per meter
* @memberof UniformState.prototype
* @type {number}
*/
geometricToleranceOverMeter: {
get: function () {
return this._geometricToleranceOverMeter;
},
},
/**
* @memberof UniformState.prototype
* @type {Pass}
*/
pass: {
get: function () {
return this._pass;
},
},
/**
* The current background color
* @memberof UniformState.prototype
* @type {Color}
*/
backgroundColor: {
get: function () {
return this._backgroundColor;
},
},
/**
* The look up texture used to find the BRDF for a material
* @memberof UniformState.prototype
* @type {Texture}
*/
brdfLut: {
get: function () {
return this._brdfLut;
},
},
/**
* The environment map of the scene
* @memberof UniformState.prototype
* @type {CubeMap}
*/
environmentMap: {
get: function () {
return this._environmentMap;
},
},
/**
* The spherical harmonic coefficients of the scene.
* @memberof UniformState.prototype
* @type {Cartesian3[]}
*/
sphericalHarmonicCoefficients: {
get: function () {
return this._sphericalHarmonicCoefficients;
},
},
/**
* The specular environment cube map of the scene.
* @memberof UniformState.prototype
* @type {Texture}
*/
specularEnvironmentMaps: {
get: function () {
return this._specularEnvironmentMaps;
},
},
/**
* The maximum level-of-detail of the specular environment cube map of the scene.
* @memberof UniformState.prototype
* @type {number}
*/
specularEnvironmentMapsMaximumLOD: {
get: function () {
return this._specularEnvironmentMapsMaximumLOD;
},
},
/**
* The splitter position to use when rendering with a splitter. This will be in pixel coordinates relative to the canvas.
* @memberof UniformState.prototype
* @type {number}
*/
splitPosition: {
get: function () {
return this._splitPosition;
},
},
/**
* The distance from the camera at which to disable the depth test of billboards, labels and points
* to, for example, prevent clipping against terrain. When set to zero, the depth test should always
* be applied. When less than zero, the depth test should never be applied.
*
* @memberof UniformState.prototype
* @type {number}
*/
minimumDisableDepthTestDistance: {
get: function () {
return this._minimumDisableDepthTestDistance;
},
},
/**
* The highlight color of unclassified 3D Tiles.
*
* @memberof UniformState.prototype
* @type {Color}
*/
invertClassificationColor: {
get: function () {
return this._invertClassificationColor;
},
},
/**
* Whether or not the current projection is orthographic in 3D.
*
* @memberOf UniformState.prototype
* @type {boolean}
*/
orthographicIn3D: {
get: function () {
return this._orthographicIn3D;
},
},
/**
* The current ellipsoid.
*
* @memberOf UniformState.prototype
* @type {Ellipsoid}
*/
ellipsoid: {
get: function () {
return this._ellipsoid ?? Ellipsoid.default;
},
},
});
function setView(uniformState, matrix) {
Matrix4.clone(matrix, uniformState._view);
Matrix4.getMatrix3(matrix, uniformState._viewRotation);
uniformState._view3DDirty = true;
uniformState._inverseView3DDirty = true;
uniformState._modelViewDirty = true;
uniformState._modelView3DDirty = true;
uniformState._modelViewRelativeToEyeDirty = true;
uniformState._inverseModelViewDirty = true;
uniformState._inverseModelView3DDirty = true;
uniformState._viewProjectionDirty = true;
uniformState._inverseViewProjectionDirty = true;
uniformState._modelViewProjectionDirty = true;
uniformState._modelViewProjectionRelativeToEyeDirty = true;
uniformState._modelViewInfiniteProjectionDirty = true;
uniformState._normalDirty = true;
uniformState._inverseNormalDirty = true;
uniformState._normal3DDirty = true;
uniformState._inverseNormal3DDirty = true;
}
function setInverseView(uniformState, matrix) {
Matrix4.clone(matrix, uniformState._inverseView);
Matrix4.getMatrix3(matrix, uniformState._inverseViewRotation);
}
function setProjection(uniformState, matrix) {
Matrix4.clone(matrix, uniformState._projection);
uniformState._inverseProjectionDirty = true;
uniformState._viewProjectionDirty = true;
uniformState._inverseViewProjectionDirty = true;
uniformState._modelViewProjectionDirty = true;
uniformState._modelViewProjectionRelativeToEyeDirty = true;
}
function setInfiniteProjection(uniformState, matrix) {
Matrix4.clone(matrix, uniformState._infiniteProjection);
uniformState._modelViewInfiniteProjectionDirty = true;
}
const surfacePositionScratch = new Cartesian3();
const enuTransformScratch = new Matrix4();
function setCamera(uniformState, camera) {
Cartesian3.clone(camera.positionWC, uniformState._cameraPosition);
Cartesian3.clone(camera.directionWC, uniformState._cameraDirection);
Cartesian3.clone(camera.rightWC, uniformState._cameraRight);
Cartesian3.clone(camera.upWC, uniformState._cameraUp);
const ellipsoid = uniformState._ellipsoid;
let surfacePosition;
const positionCartographic = camera.positionCartographic;
if (!defined(positionCartographic)) {
uniformState._eyeHeight = -ellipsoid.maximumRadius;
if (Cartesian3.magnitude(camera.positionWC) > 0.0) {
uniformState._eyeEllipsoidNormalEC = Cartesian3.normalize(
camera.positionWC,
uniformState._eyeEllipsoidNormalEC,
);
}
surfacePosition = ellipsoid.scaleToGeodeticSurface(
camera.positionWC,
surfacePositionScratch,
);
} else {
uniformState._eyeHeight = positionCartographic.height;
uniformState._eyeEllipsoidNormalEC =
ellipsoid.geodeticSurfaceNormalCartographic(
positionCartographic,
uniformState._eyeEllipsoidNormalEC,
);
surfacePosition = Cartesian3.fromRadians(
positionCartographic.longitude,
positionCartographic.latitude,
0.0,
ellipsoid,
surfacePositionScratch,
);
}
uniformState._encodedCameraPositionMCDirty = true;
if (!defined(surfacePosition)) {
return;
}
uniformState._eyeEllipsoidNormalEC = Matrix3.multiplyByVector(
uniformState._viewRotation,
uniformState._eyeEllipsoidNormalEC,
uniformState._eyeEllipsoidNormalEC,
);
const enuToWorld = Transforms.eastNorthUpToFixedFrame(
surfacePosition,
ellipsoid,
enuTransformScratch,
);
uniformState._enuToModel = Matrix4.multiplyTransformation(
uniformState.inverseModel,
enuToWorld,
uniformState._enuToModel,
);
uniformState._modelToEnu = Matrix4.inverseTransformation(
uniformState._enuToModel,
uniformState._modelToEnu,
);
if (
!CesiumMath.equalsEpsilon(
ellipsoid._radii.x,
ellipsoid._radii.y,
CesiumMath.EPSILON15,
)
) {
// Ellipsoid curvature calculations assume radii.x === radii.y as is true for WGS84
return;
}
uniformState._eyeEllipsoidCurvature = ellipsoid.getLocalCurvature(
surfacePosition,
uniformState._eyeEllipsoidCurvature,
);
}
const transformMatrix = new Matrix3();
const sunCartographicScratch = new Cartographic();
function setSunAndMoonDirections(uniformState, frameState) {
Transforms.computeIcrfToCentralBodyFixedMatrix(
frameState.time,
transformMatrix,
);
let position =
Simon1994PlanetaryPositions.computeSunPositionInEarthInertialFrame(
frameState.time,
uniformState._sunPositionWC,
);
Matrix3.multiplyByVector(transformMatrix, position, position);
Cartesian3.normalize(position, uniformState._sunDirectionWC);
position = Matrix3.multiplyByVector(
uniformState.viewRotation3D,
position,
uniformState._sunDirectionEC,
);
Cartesian3.normalize(position, position);
position =
Simon1994PlanetaryPositions.computeMoonPositionInEarthInertialFrame(
frameState.time,
uniformState._moonDirectionEC,
);
Matrix3.multiplyByVector(transformMatrix, position, position);
Matrix3.multiplyByVector(uniformState.viewRotation3D, position, position);
Cartesian3.normalize(position, position);
const projection = frameState.mapProjection;
const ellipsoid = projection.ellipsoid;
const sunCartographic = ellipsoid.cartesianToCartographic(
uniformState._sunPositionWC,
sunCartographicScratch,
);
projection.project(sunCartographic, uniformState._sunPositionColumbusView);
}
/**
* Synchronizes the frustum's state with the camera state. This is called
* by the {@link Scene} when rendering to ensure that automatic GLSL uniforms
* are set to the right value.
*
* @param {object} camera The camera to synchronize with.
*/
UniformState.prototype.updateCamera = function (camera) {
setView(this, camera.viewMatrix);
setInverseView(this, camera.inverseViewMatrix);
setCamera(this, camera);
this._entireFrustum.x = camera.frustum.near;
this._entireFrustum.y = camera.frustum.far;
this.updateFrustum(camera.frustum);
this._orthographicIn3D =
this._mode !== SceneMode.SCENE2D &&
camera.frustum instanceof OrthographicFrustum;
};
/**
* Synchronizes the frustum's state with the uniform state. This is called
* by the {@link Scene} when rendering to ensure that automatic GLSL uniforms
* are set to the right value.
*
* @param {object} frustum The frustum to synchronize with.
*/
UniformState.prototype.updateFrustum = function (frustum) {
// If any frustum parameters have changed, calling the frustum.projectionMatrix
// getter will recompute the projection before it is copied.
setProjection(this, frustum.projectionMatrix);
if (defined(frustum.infiniteProjectionMatrix)) {
setInfiniteProjection(this, frustum.infiniteProjectionMatrix);
}
this._currentFrustum.x = frustum.near;
this._currentFrustum.y = frustum.far;
this._farDepthFromNearPlusOne = frustum.far - frustum.near + 1.0;
this._log2FarDepthFromNearPlusOne = CesiumMath.log2(
this._farDepthFromNearPlusOne,
);
this._oneOverLog2FarDepthFromNearPlusOne =
1.0 / this._log2FarDepthFromNearPlusOne;
const offCenterFrustum = frustum.offCenterFrustum;
if (defined(offCenterFrustum)) {
frustum = offCenterFrustum;
}
this._frustumPlanes.x = frustum.top;
this._frustumPlanes.y = frustum.bottom;
this._frustumPlanes.z = frustum.left;
this._frustumPlanes.w = frustum.right;
};
UniformState.prototype.updatePass = function (pass) {
this._pass = pass;
};
const EMPTY_ARRAY = [];
const defaultLight = new SunLight();
/**
* Synchronizes frame state with the uniform state. This is called
* by the {@link Scene} when rendering to ensure that automatic GLSL uniforms
* are set to the right value.
*
* @param {FrameState} frameState The frameState to synchronize with.
*/
UniformState.prototype.update = function (frameState) {
this._mode = frameState.mode;
this._mapProjection = frameState.mapProjection;
this._ellipsoid = frameState.mapProjection.ellipsoid;
this._pixelRatio = frameState.pixelRatio;
const camera = frameState.camera;
this.updateCamera(camera);
if (frameState.mode === SceneMode.SCENE2D) {
this._frustum2DWidth = camera.frustum.right - camera.frustum.left;
this._eyeHeight2D.x = this._frustum2DWidth * 0.5;
this._eyeHeight2D.y = this._eyeHeight2D.x * this._eyeHeight2D.x;
} else {
this._frustum2DWidth = 0.0;
this._eyeHeight2D.x = 0.0;
this._eyeHeight2D.y = 0.0;
}
setSunAndMoonDirections(this, frameState);
const light = frameState.light ?? defaultLight;
if (light instanceof SunLight) {
this._lightDirectionWC = Cartesian3.clone(
this._sunDirectionWC,
this._lightDirectionWC,
);
this._lightDirectionEC = Cartesian3.clone(
this._sunDirectionEC,
this._lightDirectionEC,
);
} else {
this._lightDirectionWC = Cartesian3.normalize(
Cartesian3.negate(light.direction, this._lightDirectionWC),
this._lightDirectionWC,
);
this._lightDirectionEC = Matrix3.multiplyByVector(
this.viewRotation3D,
this._lightDirectionWC,
this._lightDirectionEC,
);
}
const lightColor = light.color;
let lightColorHdr = Cartesian3.fromElements(
lightColor.red,
lightColor.green,
lightColor.blue,
this._lightColorHdr,
);
lightColorHdr = Cartesian3.multiplyByScalar(
lightColorHdr,
light.intensity,
lightColorHdr,
);
const maximumComponent = Cartesian3.maximumComponent(lightColorHdr);
if (maximumComponent > 1.0) {
Cartesian3.divideByScalar(
lightColorHdr,
maximumComponent,
this._lightColor,
);
} else {
Cartesian3.clone(lightColorHdr, this._lightColor);
}
const brdfLutGenerator = frameState.brdfLutGenerator;
const brdfLut = defined(brdfLutGenerator)
? brdfLutGenerator.colorTexture
: undefined;
this._brdfLut = brdfLut;
this._environmentMap =
frameState.environmentMap ?? frameState.context.defaultCubeMap;
// IE 11 doesn't optimize out uniforms that are #ifdef'd out. So undefined values for the spherical harmonic
// coefficients cause a crash.
this._sphericalHarmonicCoefficients =
frameState.sphericalHarmonicCoefficients ?? EMPTY_ARRAY;
this._specularEnvironmentMaps = frameState.specularEnvironmentMaps;
this._specularEnvironmentMapsMaximumLOD =
frameState.specularEnvironmentMapsMaximumLOD;
this._fogDensity = frameState.fog.density;
this._fogVisualDensityScalar = frameState.fog.visualDensityScalar;
this._fogMinimumBrightness = frameState.fog.minimumBrightness;
const atmosphere = frameState.atmosphere;
if (defined(atmosphere)) {
this._atmosphereHsbShift = Cartesian3.fromElements(
atmosphere.hueShift,
atmosphere.saturationShift,
atmosphere.brightnessShift,
this._atmosphereHsbShift,
);
this._atmosphereLightIntensity = atmosphere.lightIntensity;
this._atmosphereRayleighCoefficient = Cartesian3.clone(
atmosphere.rayleighCoefficient,
this._atmosphereRayleighCoefficient,
);
this._atmosphereRayleighScaleHeight = atmosphere.rayleighScaleHeight;
this._atmosphereMieCoefficient = Cartesian3.clone(
atmosphere.mieCoefficient,
this._atmosphereMieCoefficient,
);
this._atmosphereMieScaleHeight = atmosphere.mieScaleHeight;
this._atmosphereMieAnisotropy = atmosphere.mieAnisotropy;
this._atmosphereDynamicLighting = atmosphere.dynamicLighting;
}
this._invertClassificationColor = frameState.invertClassificationColor;
this._frameState = frameState;
this._temeToPseudoFixed = Transforms.computeTemeToPseudoFixedMatrix(
frameState.time,
this._temeToPseudoFixed,
);
// Convert the relative splitPosition to absolute pixel coordinates
this._splitPosition =
frameState.splitPosition * frameState.context.drawingBufferWidth;
const fov = camera.frustum.fov;
const viewport = this._viewport;
let pixelSizePerMeter;
if (defined(fov)) {
if (viewport.height > viewport.width) {
pixelSizePerMeter = (Math.tan(0.5 * fov) * 2.0) / viewport.height;
} else {
pixelSizePerMeter = (Math.tan(0.5 * fov) * 2.0) / viewport.width;
}
} else {
pixelSizePerMeter = 1.0 / Math.max(viewport.width, viewport.height);
}
this._geometricToleranceOverMeter =
pixelSizePerMeter * frameState.maximumScreenSpaceError;
Color.clone(frameState.backgroundColor, this._backgroundColor);
this._minimumDisableDepthTestDistance =
frameState.minimumDisableDepthTestDistance;
this._minimumDisableDepthTestDistance *=
this._minimumDisableDepthTestDistance;
if (this._minimumDisableDepthTestDistance === Number.POSITIVE_INFINITY) {
this._minimumDisableDepthTestDistance = -1.0;
}
};
function cleanViewport(uniformState) {
if (uniformState._viewportDirty) {
const v = uniformState._viewport;
Matrix4.computeOrthographicOffCenter(
v.x,
v.x + v.width,
v.y,
v.y + v.height,
0.0,
1.0,
uniformState._viewportOrthographicMatrix,
);
Matrix4.computeViewportTransformation(
v,
0.0,
1.0,
uniformState._viewportTransformation,
);
uniformState._viewportDirty = false;
}
}
function cleanInverseProjection(uniformState) {
if (uniformState._inverseProjectionDirty) {
uniformState._inverseProjectionDirty = false;
if (
uniformState._mode !== SceneMode.SCENE2D &&
uniformState._mode !== SceneMode.MORPHING &&
!uniformState._orthographicIn3D
) {
Matrix4.inverse(
uniformState._projection,
uniformState._inverseProjection,
);
} else {
Matrix4.clone(Matrix4.ZERO, uniformState._inverseProjection);
}
}
}
// Derived
function cleanModelView(uniformState) {
if (uniformState._modelViewDirty) {
uniformState._modelViewDirty = false;
Matrix4.multiplyTransformation(
uniformState._view,
uniformState._model,
uniformState._modelView,
);
}
}
function cleanModelView3D(uniformState) {
if (uniformState._modelView3DDirty) {
uniformState._modelView3DDirty = false;
Matrix4.multiplyTransformation(
uniformState.view3D,
uniformState._model,
uniformState._modelView3D,
);
}
}
function cleanInverseModelView(uniformState) {
if (uniformState._inverseModelViewDirty) {
uniformState._inverseModelViewDirty = false;
Matrix4.inverse(uniformState.modelView, uniformState._inverseModelView);
}
}
function cleanInverseModelView3D(uniformState) {
if (uniformState._inverseModelView3DDirty) {
uniformState._inverseModelView3DDirty = false;
Matrix4.inverse(uniformState.modelView3D, uniformState._inverseModelView3D);
}
}
function cleanViewProjection(uniformState) {
if (uniformState._viewProjectionDirty) {
uniformState._viewProjectionDirty = false;
Matrix4.multiply(
uniformState._projection,
uniformState._view,
uniformState._viewProjection,
);
}
}
function cleanInverseViewProjection(uniformState) {
if (uniformState._inverseViewProjectionDirty) {
uniformState._inverseViewProjectionDirty = false;
Matrix4.inverse(
uniformState.viewProjection,
uniformState._inverseViewProjection,
);
}
}
function cleanModelViewProjection(uniformState) {
if (uniformState._modelViewProjectionDirty) {
uniformState._modelViewProjectionDirty = false;
Matrix4.multiply(
uniformState._projection,
uniformState.modelView,
uniformState._modelViewProjection,
);
}
}
function cleanModelViewRelativeToEye(uniformState) {
if (uniformState._modelViewRelativeToEyeDirty) {
uniformState._modelViewRelativeToEyeDirty = false;
const mv = uniformState.modelView;
const mvRte = uniformState._modelViewRelativeToEye;
mvRte[0] = mv[0];
mvRte[1] = mv[1];
mvRte[2] = mv[2];
mvRte[3] = mv[3];
mvRte[4] = mv[4];
mvRte[5] = mv[5];
mvRte[6] = mv[6];
mvRte[7] = mv[7];
mvRte[8] = mv[8];
mvRte[9] = mv[9];
mvRte[10] = mv[10];
mvRte[11] = mv[11];
mvRte[12] = 0.0;
mvRte[13] = 0.0;
mvRte[14] = 0.0;
mvRte[15] = mv[15];
}
}
function cleanInverseModelViewProjection(uniformState) {
if (uniformState._inverseModelViewProjectionDirty) {
uniformState._inverseModelViewProjectionDirty = false;
Matrix4.inverse(
uniformState.modelViewProjection,
uniformState._inverseModelViewProjection,
);
}
}
function cleanModelViewProjectionRelativeToEye(uniformState) {
if (uniformState._modelViewProjectionRelativeToEyeDirty) {
uniformState._modelViewProjectionRelativeToEyeDirty = false;
Matrix4.multiply(
uniformState._projection,
uniformState.modelViewRelativeToEye,
uniformState._modelViewProjectionRelativeToEye,
);
}
}
function cleanModelViewInfiniteProjection(uniformState) {
if (uniformState._modelViewInfiniteProjectionDirty) {
uniformState._modelViewInfiniteProjectionDirty = false;
Matrix4.multiply(
uniformState._infiniteProjection,
uniformState.modelView,
uniformState._modelViewInfiniteProjection,
);
}
}
function cleanNormal(uniformState) {
if (uniformState._normalDirty) {
uniformState._normalDirty = false;
const m = uniformState._normal;
Matrix4.getMatrix3(uniformState.inverseModelView, m);
Matrix3.transpose(m, m);
}
}
function cleanNormal3D(uniformState) {
if (uniformState._normal3DDirty) {
uniformState._normal3DDirty = false;
const m = uniformState._normal3D;
Matrix4.getMatrix3(uniformState.inverseModelView3D, m);
Matrix3.transpose(m, m);
}
}
function cleanInverseNormal(uniformState) {
if (uniformState._inverseNormalDirty) {
uniformState._inverseNormalDirty = false;
const m = uniformState._inverseNormal;
Matrix4.getMatrix3(uniformState.modelView, m);
Matrix3.transpose(m, m);
}
}
function cleanInverseNormal3D(uniformState) {
if (uniformState._inverseNormal3DDirty) {
uniformState._inverseNormal3DDirty = false;
const m = uniformState._inverseNormal3D;
Matrix4.getMatrix3(uniformState.modelView3D, m);
Matrix3.transpose(m, m);
}
}
const cameraPositionMC = new Cartesian3();
function cleanEncodedCameraPositionMC(uniformState) {
if (uniformState._encodedCameraPositionMCDirty) {
uniformState._encodedCameraPositionMCDirty = false;
Matrix4.multiplyByPoint(
uniformState.inverseModel,
uniformState._cameraPosition,
cameraPositionMC,
);
EncodedCartesian3.fromCartesian(
cameraPositionMC,
uniformState._encodedCameraPositionMC,
);
}
}
const view2Dto3DPScratch = new Cartesian3();
const view2Dto3DRScratch = new Cartesian3();
const view2Dto3DUScratch = new Cartesian3();
const view2Dto3DDScratch = new Cartesian3();
const view2Dto3DCartographicScratch = new Cartographic();
const view2Dto3DCartesian3Scratch = new Cartesian3();
const view2Dto3DMatrix4Scratch = new Matrix4();
function view2Dto3D(
position2D,
direction2D,
right2D,
up2D,
frustum2DWidth,
mode,
projection,
result,
) {
// The camera position and directions are expressed in the 2D coordinate system where the Y axis is to the East,
// the Z axis is to the North, and the X axis is out of the map. Express them instead in the ENU axes where
// X is to the East, Y is to the North, and Z is out of the local horizontal plane.
const p = view2Dto3DPScratch;
p.x = position2D.y;
p.y = position2D.z;
p.z = position2D.x;
const r = view2Dto3DRScratch;
r.x = right2D.y;
r.y = right2D.z;
r.z = right2D.x;
const u = view2Dto3DUScratch;
u.x = up2D.y;
u.y = up2D.z;
u.z = up2D.x;
const d = view2Dto3DDScratch;
d.x = direction2D.y;
d.y = direction2D.z;
d.z = direction2D.x;
// In 2D, the camera height is always 12.7 million meters.
// The apparent height is equal to half the frustum width.
if (mode === SceneMode.SCENE2D) {
p.z = frustum2DWidth * 0.5;
}
// Compute the equivalent camera position in the real (3D) world.
// In 2D and Columbus View, the camera can travel outside the projection, and when it does so
// there's not really any cor