From f6c08c88ca98d903051d523143f8fb815f13b9fb Mon Sep 17 00:00:00 2001 From: ggetz Date: Tue, 21 Oct 2025 15:04:58 -0400 Subject: [PATCH 1/2] Depth test billboards against ellipsoid horizon --- .../Source/Shaders/BillboardCollectionFS.glsl | 10 +++++----- .../Source/Shaders/BillboardCollectionVS.glsl | 16 ++++++++++++++-- packages/sandcastle/gallery/mars/main.js | 6 ------ packages/sandcastle/gallery/moon/main.js | 6 ------ 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/engine/Source/Shaders/BillboardCollectionFS.glsl b/packages/engine/Source/Shaders/BillboardCollectionFS.glsl index 74d21300a95e..02d9be2f2935 100644 --- a/packages/engine/Source/Shaders/BillboardCollectionFS.glsl +++ b/packages/engine/Source/Shaders/BillboardCollectionFS.glsl @@ -9,7 +9,7 @@ uniform vec4 u_highlightColor; in vec2 v_textureCoordinates; in vec4 v_pickColor; in vec4 v_color; -in float v_splitDirection; +in vec2 v_splitDirectionAndEllipsoidDepthEC; #ifdef SDF in vec4 v_outlineColor; @@ -164,8 +164,8 @@ void doDepthTest() { float globeDepth = getGlobeDepthAtCoords(fragSt); if (globeDepth == 0.0) return; // Not on globe - float distanceToEllipsoidCenter = -length(czm_viewerPositionWC); // depth is negative by convention - float testDistance = (eyeDepth > -u_coarseDepthTestDistance) ? globeDepth : distanceToEllipsoidCenter; + float distanceToEllipsoid = -v_splitDirectionAndEllipsoidDepthEC.y; // depth is negative by convention + float testDistance = (eyeDepth > -u_coarseDepthTestDistance) ? globeDepth : distanceToEllipsoid; if (eyeDepth < testDistance) { discard; } @@ -173,8 +173,8 @@ void doDepthTest() { void main() { - if (v_splitDirection < 0.0 && gl_FragCoord.x > czm_splitPosition) discard; - if (v_splitDirection > 0.0 && gl_FragCoord.x < czm_splitPosition) discard; + if (v_splitDirectionAndEllipsoidDepthEC.x < 0.0 && gl_FragCoord.x > czm_splitPosition) discard; + if (v_splitDirectionAndEllipsoidDepthEC.x > 0.0 && gl_FragCoord.x < czm_splitPosition) discard; doDepthTest(); vec4 color = texture(u_atlas, v_textureCoordinates); diff --git a/packages/engine/Source/Shaders/BillboardCollectionVS.glsl b/packages/engine/Source/Shaders/BillboardCollectionVS.glsl index c258b09bb104..2338a456e0e2 100644 --- a/packages/engine/Source/Shaders/BillboardCollectionVS.glsl +++ b/packages/engine/Source/Shaders/BillboardCollectionVS.glsl @@ -30,7 +30,7 @@ out vec4 v_compressed; // x: eyeDepth, y: applyT out vec4 v_pickColor; out vec4 v_color; -out float v_splitDirection; +out vec2 v_splitDirectionAndEllipsoidDepthEC; // x: splitDirection, y: ellipsoid depth in eye coordinates #ifdef SDF out vec4 v_outlineColor; out float v_outlineWidth; @@ -322,6 +322,18 @@ void main() } #endif + v_splitDirectionAndEllipsoidDepthEC.y = czm_infinity; + vec3 ellipsoidCenter = czm_view[3].xyz; + vec3 rayDirection = normalize(positionEC.xyz); + czm_ray ray = czm_ray(vec3(0.0), rayDirection); + vec3 ellipsoid_inverseRadii = czm_ellipsoidInverseRadii; + czm_raySegment intersection = czm_rayEllipsoidIntersectionInterval(ray, ellipsoidCenter, ellipsoid_inverseRadii); + + if (!czm_isEmpty(intersection)) + { + v_splitDirectionAndEllipsoidDepthEC.y = intersection.start; + } + v_compressed.y = enableDepthCheck; #ifdef VS_THREE_POINT_DEPTH_CHECK @@ -441,5 +453,5 @@ if (lengthSq < (u_threePointDepthTestDistance * u_threePointDepthTestDistance) & v_color = color; v_color.a *= translucency; - v_splitDirection = splitDirection; + v_splitDirectionAndEllipsoidDepthEC.x = splitDirection; } diff --git a/packages/sandcastle/gallery/mars/main.js b/packages/sandcastle/gallery/mars/main.js index 5f09cbc671bc..01547e57189d 100644 --- a/packages/sandcastle/gallery/mars/main.js +++ b/packages/sandcastle/gallery/mars/main.js @@ -201,9 +201,6 @@ try { scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1.0, 1.5e7, 0.5), translucencyByDistance: new Cesium.NearFarScalar(2.5e7, 1.0, 4.0e7, 0.0), heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - disableDepthTestDistance: new Cesium.CallbackProperty(() => { - return Cesium.Cartesian3.magnitude(scene.camera.positionWC); - }, false), }); entity.point = new Cesium.PointGraphics({ @@ -213,9 +210,6 @@ try { outlineWidth: 2, scaleByDistance: new Cesium.NearFarScalar(1.5e3, 1.0, 4.0e7, 0.1), heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - disableDepthTestDistance: new Cesium.CallbackProperty(() => { - return Cesium.Cartesian3.magnitude(scene.camera.positionWC); - }, false), }); entity.name = entity.properties.text.getValue(); diff --git a/packages/sandcastle/gallery/moon/main.js b/packages/sandcastle/gallery/moon/main.js index eb72ef107e3f..58b7f572f2f5 100644 --- a/packages/sandcastle/gallery/moon/main.js +++ b/packages/sandcastle/gallery/moon/main.js @@ -87,9 +87,6 @@ for (const poi of pointsOfInterest) { scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1.0, 1.5e7, 0.5), translucencyByDistance: new Cesium.NearFarScalar(2.5e7, 1.0, 4.0e7, 0.0), heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - disableDepthTestDistance: new Cesium.CallbackProperty(() => { - return Cesium.Cartesian3.magnitude(scene.camera.positionWC); - }, false), }, point: { pixelSize: 10, @@ -98,9 +95,6 @@ for (const poi of pointsOfInterest) { outlineWidth: 2, scaleByDistance: new Cesium.NearFarScalar(1.5e3, 1.0, 4.0e7, 0.1), heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - disableDepthTestDistance: new Cesium.CallbackProperty(() => { - return Cesium.Cartesian3.magnitude(scene.camera.positionWC); - }, false), }, }); } From df18023b264ec052a0fb6e0799642ec61f2dbbe4 Mon Sep 17 00:00:00 2001 From: ggetz Date: Wed, 22 Oct 2025 17:20:57 -0400 Subject: [PATCH 2/2] Delta depth test for billboards --- .../engine/Source/Shaders/BillboardCollectionFS.glsl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/engine/Source/Shaders/BillboardCollectionFS.glsl b/packages/engine/Source/Shaders/BillboardCollectionFS.glsl index 02d9be2f2935..c0284c48f4a4 100644 --- a/packages/engine/Source/Shaders/BillboardCollectionFS.glsl +++ b/packages/engine/Source/Shaders/BillboardCollectionFS.glsl @@ -164,9 +164,13 @@ void doDepthTest() { float globeDepth = getGlobeDepthAtCoords(fragSt); if (globeDepth == 0.0) return; // Not on globe - float distanceToEllipsoid = -v_splitDirectionAndEllipsoidDepthEC.y; // depth is negative by convention - float testDistance = (eyeDepth > -u_coarseDepthTestDistance) ? globeDepth : distanceToEllipsoid; - if (eyeDepth < testDistance) { + float distanceToEllipsoid = -v_splitDirectionAndEllipsoidDepthEC.y; + bool useGlobeDepth = eyeDepth > -u_coarseDepthTestDistance; + float testDistance = useGlobeDepth ? globeDepth : distanceToEllipsoid; + float testDelta = eyeDepth - testDistance; + + float depthsilon = useGlobeDepth ? u_threePointDepthTestDistance : u_coarseDepthTestDistance; + if (testDelta < -depthsilon) { discard; } }