Hey Luke,
First of all, thank you for your response! I’ve been struggling with this issue for weeks now and still can’t find a solution.
To answer your question, yes, I am already using CLAMP_TO_GROUND. Here’s an example of how I’m implementing it. We use this setting because we need to place markers directly on top of 3D tiles:
viewer.entities.add({
position: position,
billboard: {
image: createTextBoxCanvas(),
color: cesium.Color.WHITE.withAlpha(1.0),
width: 50,
height: 50,
verticalOrigin: cesium.VerticalOrigin.BOTTOM,
heightReference: cesium.HeightReference.CLAMP_TO_3D_TILE,
disableDepthTestDistance: 0,
},
});
The issue arises because this configuration causes buggy billboards that glitch through the 3D tiles. According to the documentation, I can use disableDepthTestDistance: Number.POSITIVE_INFINITY to disable depth testing. However, this creates another problem: my labels overlap in a strange order.
Here’s a visual comparison:
• Depth testing disabled:
• What it should look like (depth testing enabled):
When I enable depth testing, the billboards start intersecting with the 3D tiles, which looks incorrect. The main reason I need depth testing enabled is that when tilting the camera, the billboards closer to the viewer should appear on top, maintaining the correct visual hierarchy.
Intersecting with 3d tiles (depth testing enabled):
No intersection (depth testing disabled)
My goal is to maintain the logical order of the entities, which I achieve by enabling depth testing, while also preventing them from intersecting with the 3D tiles as they do when depth testing is enabled.
Additional Details
Tile Set Configuration:
Here’s our tile set configuration for the Google Photorealistic 3D Tiles API:
const googleTileset = await cesium.createGooglePhotorealistic3DTileset(apiKey, {
foveatedScreenSpaceError: true,
foveatedConeSize: 0.2,
foveatedTimeDelay: 0.2,
maximumScreenSpaceError: 16,
skipLevelOfDetail: true,
skipScreenSpaceErrorFactor: 16,
skipLevels: 2,
cullRequestsWhileMoving: true,
cullRequestsWhileMovingMultiplier: 8.0,
immediatelyLoadDesiredLevelOfDetail: false,
preloadWhenHidden: true,
preloadFlightDestinations: true,
loadSiblings: true,
});
Cesium Viewer Configuration:
Here’s the relevant part of our Cesium Viewer setup:
cesiumViewer.current = new Viewer(cesiumContainerRef.current, {
terrainProvider: terrainProvider,
baseLayerPicker: false,
timeline: false,
animation: false,
navigationHelpButton: false,
homeButton: false,
fullscreenButton: false,
sceneModePicker: false,
geocoder: false,
infoBox: false,
selectionIndicator: false,
navigationInstructionsInitiallyVisible: false,
shadows: false,
});
cesiumViewer.current.cesiumWidget.creditContainer.style.display = 'none';
cesiumViewer.current.targetFrameRate = 60;
cesiumViewer.current.clock.clockStep = cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER;
cesiumViewer.current.postProcessStages.fxaa.enabled = true;
I’m happy to provide further code examples or settings if needed. Let me know if there’s anything else I can clarify.
Thank you again for your time and support!