Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Added `token`, `mapServerData`, and `parameters` properties to `ArcGisMapServerImageryProvider.ConstructorOptions`.
- Added `Ion.defaultTokenMessage` to customize the credit message shown on the map when using default Ion token.
- Added split terrain feature.

## 1.139.1 - 2026-03-05

Expand Down
11 changes: 11 additions & 0 deletions packages/engine/Source/Scene/Globe.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import ImageryLayerCollection from "./ImageryLayerCollection.js";
import QuadtreePrimitive from "./QuadtreePrimitive.js";
import SceneMode from "./SceneMode.js";
import ShadowMode from "./ShadowMode.js";
import SplitDirection from "./SplitDirection.js";
import CesiumMath from "../Core/Math.js";

/**
Expand Down Expand Up @@ -370,6 +371,15 @@ function Globe(ellipsoid) {
* @default 0.3
*/
this.vertexShadowDarkness = 0.3;

/**
* The {@link SplitDirection} to apply, showing the terrain only on
* the left or right of the splitter control.
*
* @type {SplitDirection}
* @default {@link SplitDirection.NONE}
*/
this.splitDirection = SplitDirection.NONE;
}

Object.defineProperties(Globe.prototype, {
Expand Down Expand Up @@ -1055,6 +1065,7 @@ Globe.prototype.beginFrame = function (frameState) {
tileProvider.undergroundColorAlphaByDistance =
this._undergroundColorAlphaByDistance;
tileProvider.lambertDiffuseMultiplier = this.lambertDiffuseMultiplier;
tileProvider.splitDirection = this.splitDirection;

surface.beginFrame(frameState);
}
Expand Down
8 changes: 7 additions & 1 deletion packages/engine/Source/Scene/GlobeSurfaceShaderSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
const hasExaggeration = options.hasExaggeration;
const showUndergroundColor = options.showUndergroundColor;
const translucent = options.translucent;
const splitTerrain = options.splitTerrain;

let quantization = 0;
let quantizationDefine = "";
Expand Down Expand Up @@ -197,7 +198,8 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
(showUndergroundColor << 30) |
(translucent << 31)) >>>
0) +
(applyDayNightAlpha ? 0x100000000 : 0);
(applyDayNightAlpha ? 0x100000000 : 0) +
(splitTerrain ? 0x200000000 : 0);

let currentClippingShaderState = 0;
if (defined(clippingPlanes) && clippingPlanes.length > 0) {
Expand Down Expand Up @@ -382,6 +384,10 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
vs.defines.push("EXAGGERATION");
}

if (splitTerrain) {
fs.defines.push("SPLIT_TERRAIN");
}

let computeDayColor =
"\
vec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates, float nightBlend)\n\
Expand Down
7 changes: 7 additions & 0 deletions packages/engine/Source/Scene/GlobeSurfaceTileProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import Primitive from "./Primitive.js";
import QuadtreeTileLoadState from "./QuadtreeTileLoadState.js";
import SceneMode from "./SceneMode.js";
import ShadowMode from "./ShadowMode.js";
import SplitDirection from "./SplitDirection.js";
import TerrainFillMesh from "./TerrainFillMesh.js";
import TerrainState from "./TerrainState.js";
import TileBoundingRegion from "./TileBoundingRegion.js";
Expand Down Expand Up @@ -91,6 +92,7 @@ function GlobeSurfaceTileProvider(options) {
this.showGroundAtmosphere = false;
this.shadows = ShadowMode.RECEIVE_ONLY;
this.vertexShadowDarkness = 0.3;
this.splitDirection = SplitDirection.NONE;

/**
* The color to use to highlight terrain fill tiles. If undefined, fill tiles are not
Expand Down Expand Up @@ -1859,6 +1861,9 @@ function createTileUniformMap(frameState, globeSurfaceTileProvider) {
u_vertexShadowDarkness: function () {
return this.properties.vertexShadowDarkness;
},
u_terrainSplitDirection: function () {
return globeSurfaceTileProvider.splitDirection;
},

// make a separate object so that changes to the properties are seen on
// derived commands that combine another uniform map with this one.
Expand Down Expand Up @@ -2361,6 +2366,8 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
surfaceShaderSetOptions.clippedByBoundaries = surfaceTile.clippedByBoundaries;
surfaceShaderSetOptions.hasGeodeticSurfaceNormals = hasGeodeticSurfaceNormals;
surfaceShaderSetOptions.hasExaggeration = hasExaggeration;
surfaceShaderSetOptions.splitTerrain =
tileProvider.splitDirection !== SplitDirection.NONE;

const tileImageryCollection = surfaceTile.imagery;
let imageryIndex = 0;
Expand Down
27 changes: 26 additions & 1 deletion packages/engine/Source/Scene/SkyAtmosphere.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Axis from "./Axis.js";
import BlendingState from "./BlendingState.js";
import CullFace from "./CullFace.js";
import SceneMode from "./SceneMode.js";
import SplitDirection from "./SplitDirection.js";

/**
* An atmosphere drawn around the limb of the provided ellipsoid. Based on
Expand Down Expand Up @@ -153,6 +154,16 @@ function SkyAtmosphere(ellipsoid) {
*/
this.brightnessShift = 0.0;

/**
* The {@link SplitDirection} to apply, showing the atmosphere only on
* the left or right of the splitter control.
*
* @type {SplitDirection}
* @default {@link SplitDirection.NONE}
*/
this.splitDirection = SplitDirection.NONE;
this._splitDirection = undefined;

this._hueSaturationBrightness = new Cartesian3();

// outer radius, inner radius, dynamic atmosphere color flag
Expand Down Expand Up @@ -197,6 +208,9 @@ function SkyAtmosphere(ellipsoid) {
u_atmosphereMieAnisotropy: function () {
return that.atmosphereMieAnisotropy;
},
u_splitDirection: function () {
return that.splitDirection;
},
};
}

Expand Down Expand Up @@ -298,8 +312,15 @@ SkyAtmosphere.prototype.update = function (frameState, globe) {
});
}

// Note that the splitDirection flag requires _two_ bits.
const splitDirectionFlag =
this.splitDirection === 0 ? 0 : this.splitDirection < 0.0 ? 1 : 2;

const flags =
colorCorrect | (perFragmentAtmosphere << 2) | (translucent << 3);
colorCorrect |
(perFragmentAtmosphere << 2) |
(translucent << 3) |
(splitDirectionFlag << 4);

if (flags !== this._flags) {
this._flags = flags;
Expand All @@ -318,6 +339,10 @@ SkyAtmosphere.prototype.update = function (frameState, globe) {
defines.push("GLOBE_TRANSLUCENT");
}

if (this.splitDirection !== SplitDirection.NONE) {
defines.push("SPLIT_ATMOSPHERE");
}

const vs = new ShaderSource({
defines: defines,
sources: [AtmosphereCommon, SkyAtmosphereCommon, SkyAtmosphereVS],
Expand Down
13 changes: 13 additions & 0 deletions packages/engine/Source/Shaders/GlobeFS.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ in vec2 v_clippingPosition;
flat in int v_regionIndex;
#endif

#ifdef SPLIT_TERRAIN
uniform float u_terrainSplitDirection;
#endif

#if defined(GROUND_ATMOSPHERE) || defined(FOG) && defined(DYNAMIC_ATMOSPHERE_LIGHTING) && (defined(ENABLE_VERTEX_LIGHTING) || defined(ENABLE_DAYNIGHT_SHADING))
uniform float u_minimumBrightness;
#endif
Expand Down Expand Up @@ -337,6 +341,15 @@ void main()
}
#endif

#ifdef SPLIT_TERRAIN
float splitPosition = czm_splitPosition;
if (u_terrainSplitDirection < 0.0 && gl_FragCoord.x > splitPosition) {
discard;
} else if (u_terrainSplitDirection > 0.0 && gl_FragCoord.x < splitPosition) {
discard;
}
#endif

#ifdef ENABLE_CLIPPING_PLANES
float clipDistance = clip(gl_FragCoord, u_clippingPlanes, u_clippingPlanesMatrix);
#endif
Expand Down
13 changes: 13 additions & 0 deletions packages/engine/Source/Shaders/SkyAtmosphereFS.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ in vec3 v_outerPositionWC;

uniform vec3 u_hsbShift;

#ifdef SPLIT_ATMOSPHERE
uniform float u_splitDirection;
#endif

#ifndef PER_FRAGMENT_ATMOSPHERE
in vec3 v_mieColor;
in vec3 v_rayleighColor;
Expand All @@ -11,6 +15,15 @@ in float v_translucent;

void main (void)
{
#ifdef SPLIT_ATMOSPHERE
float splitPosition = czm_splitPosition;
if (u_splitDirection < 0.0 && gl_FragCoord.x > splitPosition) {
discard;
} else if (u_splitDirection > 0.0 && gl_FragCoord.x < splitPosition) {
discard;
}
#endif

float lightEnum = u_radiiAndDynamicAtmosphereColor.z;
vec3 lightDirection = czm_getDynamicAtmosphereLightDirection(v_outerPositionWC, lightEnum);

Expand Down
Loading