Skip to content

Commit aa074e8

Browse files
zoran995na9da
andauthored
Re-add terrain and atmosphere splitting (#103)
* Re-add terrain and atmosphere splitting * Update terrain splitter code in surface shader set. (#104) * use bit 33 for splitTerrain * use bitwise operator --------- Co-authored-by: Nanda <nanda.sankaran@gmail.com>
1 parent fcb3cf9 commit aa074e8

7 files changed

Lines changed: 78 additions & 2 deletions

File tree

‎CHANGES.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

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

89
## 1.139.1 - 2026-03-05
910

‎packages/engine/Source/Scene/Globe.js‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import ImageryLayerCollection from "./ImageryLayerCollection.js";
2727
import QuadtreePrimitive from "./QuadtreePrimitive.js";
2828
import SceneMode from "./SceneMode.js";
2929
import ShadowMode from "./ShadowMode.js";
30+
import SplitDirection from "./SplitDirection.js";
3031
import CesiumMath from "../Core/Math.js";
3132

3233
/**
@@ -370,6 +371,15 @@ function Globe(ellipsoid) {
370371
* @default 0.3
371372
*/
372373
this.vertexShadowDarkness = 0.3;
374+
375+
/**
376+
* The {@link SplitDirection} to apply, showing the terrain only on
377+
* the left or right of the splitter control.
378+
*
379+
* @type {SplitDirection}
380+
* @default {@link SplitDirection.NONE}
381+
*/
382+
this.splitDirection = SplitDirection.NONE;
373383
}
374384

375385
Object.defineProperties(Globe.prototype, {
@@ -1055,6 +1065,7 @@ Globe.prototype.beginFrame = function (frameState) {
10551065
tileProvider.undergroundColorAlphaByDistance =
10561066
this._undergroundColorAlphaByDistance;
10571067
tileProvider.lambertDiffuseMultiplier = this.lambertDiffuseMultiplier;
1068+
tileProvider.splitDirection = this.splitDirection;
10581069

10591070
surface.beginFrame(frameState);
10601071
}

‎packages/engine/Source/Scene/GlobeSurfaceShaderSet.js‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
134134
const hasExaggeration = options.hasExaggeration;
135135
const showUndergroundColor = options.showUndergroundColor;
136136
const translucent = options.translucent;
137+
const splitTerrain = options.splitTerrain;
137138

138139
let quantization = 0;
139140
let quantizationDefine = "";
@@ -197,7 +198,8 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
197198
(showUndergroundColor << 30) |
198199
(translucent << 31)) >>>
199200
0) +
200-
(applyDayNightAlpha ? 0x100000000 : 0);
201+
(applyDayNightAlpha ? 0x100000000 : 0) +
202+
(splitTerrain ? 0x200000000 : 0);
201203

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

387+
if (splitTerrain) {
388+
fs.defines.push("SPLIT_TERRAIN");
389+
}
390+
385391
let computeDayColor =
386392
"\
387393
vec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates, float nightBlend)\n\

‎packages/engine/Source/Scene/GlobeSurfaceTileProvider.js‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import Primitive from "./Primitive.js";
4747
import QuadtreeTileLoadState from "./QuadtreeTileLoadState.js";
4848
import SceneMode from "./SceneMode.js";
4949
import ShadowMode from "./ShadowMode.js";
50+
import SplitDirection from "./SplitDirection.js";
5051
import TerrainFillMesh from "./TerrainFillMesh.js";
5152
import TerrainState from "./TerrainState.js";
5253
import TileBoundingRegion from "./TileBoundingRegion.js";
@@ -91,6 +92,7 @@ function GlobeSurfaceTileProvider(options) {
9192
this.showGroundAtmosphere = false;
9293
this.shadows = ShadowMode.RECEIVE_ONLY;
9394
this.vertexShadowDarkness = 0.3;
95+
this.splitDirection = SplitDirection.NONE;
9496

9597
/**
9698
* The color to use to highlight terrain fill tiles. If undefined, fill tiles are not
@@ -1859,6 +1861,9 @@ function createTileUniformMap(frameState, globeSurfaceTileProvider) {
18591861
u_vertexShadowDarkness: function () {
18601862
return this.properties.vertexShadowDarkness;
18611863
},
1864+
u_terrainSplitDirection: function () {
1865+
return globeSurfaceTileProvider.splitDirection;
1866+
},
18621867

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

23652372
const tileImageryCollection = surfaceTile.imagery;
23662373
let imageryIndex = 0;

‎packages/engine/Source/Scene/SkyAtmosphere.js‎

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import Axis from "./Axis.js";
2121
import BlendingState from "./BlendingState.js";
2222
import CullFace from "./CullFace.js";
2323
import SceneMode from "./SceneMode.js";
24+
import SplitDirection from "./SplitDirection.js";
2425

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

157+
/**
158+
* The {@link SplitDirection} to apply, showing the atmosphere only on
159+
* the left or right of the splitter control.
160+
*
161+
* @type {SplitDirection}
162+
* @default {@link SplitDirection.NONE}
163+
*/
164+
this.splitDirection = SplitDirection.NONE;
165+
this._splitDirection = undefined;
166+
156167
this._hueSaturationBrightness = new Cartesian3();
157168

158169
// outer radius, inner radius, dynamic atmosphere color flag
@@ -197,6 +208,9 @@ function SkyAtmosphere(ellipsoid) {
197208
u_atmosphereMieAnisotropy: function () {
198209
return that.atmosphereMieAnisotropy;
199210
},
211+
u_splitDirection: function () {
212+
return that.splitDirection;
213+
},
200214
};
201215
}
202216

@@ -298,8 +312,15 @@ SkyAtmosphere.prototype.update = function (frameState, globe) {
298312
});
299313
}
300314

315+
// Note that the splitDirection flag requires _two_ bits.
316+
const splitDirectionFlag =
317+
this.splitDirection === 0 ? 0 : this.splitDirection < 0.0 ? 1 : 2;
318+
301319
const flags =
302-
colorCorrect | (perFragmentAtmosphere << 2) | (translucent << 3);
320+
colorCorrect |
321+
(perFragmentAtmosphere << 2) |
322+
(translucent << 3) |
323+
(splitDirectionFlag << 4);
303324

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

342+
if (this.splitDirection !== SplitDirection.NONE) {
343+
defines.push("SPLIT_ATMOSPHERE");
344+
}
345+
321346
const vs = new ShaderSource({
322347
defines: defines,
323348
sources: [AtmosphereCommon, SkyAtmosphereCommon, SkyAtmosphereVS],

‎packages/engine/Source/Shaders/GlobeFS.glsl‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ in vec2 v_clippingPosition;
8383
flat in int v_regionIndex;
8484
#endif
8585

86+
#ifdef SPLIT_TERRAIN
87+
uniform float u_terrainSplitDirection;
88+
#endif
89+
8690
#if defined(GROUND_ATMOSPHERE) || defined(FOG) && defined(DYNAMIC_ATMOSPHERE_LIGHTING) && (defined(ENABLE_VERTEX_LIGHTING) || defined(ENABLE_DAYNIGHT_SHADING))
8791
uniform float u_minimumBrightness;
8892
#endif
@@ -337,6 +341,15 @@ void main()
337341
}
338342
#endif
339343

344+
#ifdef SPLIT_TERRAIN
345+
float splitPosition = czm_splitPosition;
346+
if (u_terrainSplitDirection < 0.0 && gl_FragCoord.x > splitPosition) {
347+
discard;
348+
} else if (u_terrainSplitDirection > 0.0 && gl_FragCoord.x < splitPosition) {
349+
discard;
350+
}
351+
#endif
352+
340353
#ifdef ENABLE_CLIPPING_PLANES
341354
float clipDistance = clip(gl_FragCoord, u_clippingPlanes, u_clippingPlanesMatrix);
342355
#endif

‎packages/engine/Source/Shaders/SkyAtmosphereFS.glsl‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ in vec3 v_outerPositionWC;
22

33
uniform vec3 u_hsbShift;
44

5+
#ifdef SPLIT_ATMOSPHERE
6+
uniform float u_splitDirection;
7+
#endif
8+
59
#ifndef PER_FRAGMENT_ATMOSPHERE
610
in vec3 v_mieColor;
711
in vec3 v_rayleighColor;
@@ -11,6 +15,15 @@ in float v_translucent;
1115

1216
void main (void)
1317
{
18+
#ifdef SPLIT_ATMOSPHERE
19+
float splitPosition = czm_splitPosition;
20+
if (u_splitDirection < 0.0 && gl_FragCoord.x > splitPosition) {
21+
discard;
22+
} else if (u_splitDirection > 0.0 && gl_FragCoord.x < splitPosition) {
23+
discard;
24+
}
25+
#endif
26+
1427
float lightEnum = u_radiiAndDynamicAtmosphereColor.z;
1528
vec3 lightDirection = czm_getDynamicAtmosphereLightDirection(v_outerPositionWC, lightEnum);
1629

0 commit comments

Comments
 (0)