How to achieve in Cesium that, after setting a 3D object to be transparent, it can still occlude objects behind it? Below is an example I created using Three.js, similar to the effect of colorWrite = false in Three.js. Here is my code.

How to achieve in Cesium that, after setting a 3D object to be transparent, it can still occlude objects behind it? Below is an example I created using Three.js, similar to the effect of colorWrite = false in Three.js. Here is my code.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Three.js Invisible Occluder Example</title>
    <style>
        body {
            margin: 0;
            background-color: blanchedalmond;
        }

        canvas {
            display: block;
        }
    </style>
</head>
<body>
    <canvas id="myCanvas" width="800" height="600"></canvas>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script>
        // Scene, Camera, Renderer  
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer({
            canvas: myCanvas,
            alpha: true
        });

        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        // Geometry for the front object  
        var geometry1 = new THREE.SphereGeometry(1, 64, 64);
        // Create a material that only writes to the depth buffer  
        const material1 = new THREE.MeshBasicMaterial({
            colorWrite: false // Disable color writing  
        });
        const cube1 = new THREE.Mesh(geometry1, material1);
        scene.add(cube1);

        // Geometry and Material for the back object  
        const geometry2 = new THREE.BoxGeometry(2, 2, 2);
        const material2 = new THREE.MeshBasicMaterial({ color: 0x0000ff, transparent: true, opacity: 0.5 });
        const cube2 = new THREE.Mesh(geometry2, material2);
        cube2.position.set(1, 1, -1);  // Position the back object behind the front object  
        scene.add(cube2);

        camera.position.z = 5;

        // Animation loop  
        function animate() {
            requestAnimationFrame(animate);

            // Rotate the cubes for better visibility  
            cube1.rotation.x += 0.01;
            cube1.rotation.y += 0.01;
            cube2.rotation.x += 0.01;
            cube2.rotation.y += 0.01;

            renderer.render(scene, camera);
        }
        animate();  
    </script>
</body>
</html>


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Cesium Simple Geometry</title>
    <script src="https://cesium.com/downloads/cesiumjs/releases/1.88/Build/Cesium/Cesium.js"></script>
    <style>
        @import url("https://cesium.com/downloads/cesiumjs/releases/1.88/Build/Cesium/Widgets/widgets.css");

        html,
        body,
        #cesiumContainer {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            overflow: hidden;
            background: transparent;
        }

        #cesiumContainer,
        canvas {
            position: absolute;
            top: 0;
            left: 0;
            background: transparent;
        }

        body {
            background-color: #4d7554;
        }
    </style>

</head>

<body>
    <div id="cesiumContainer"></div>
    <script>

        var viewer = new Cesium.Viewer('cesiumContainer', {
            imageryProvider: false, // Disable default imagery  
            baseLayerPicker: false, // Hide the base layer picker  
            terrainProvider: false, // Disable terrain  
            geocoder: false, // Disable geocoder  
            homeButton: false, // Disable home button  
            sceneModePicker: false, // Disable scene mode picker  
            navigationHelpButton: false, // Disable navigation help button  
            animation: false, // Disable animation widget  
            timeline: false, // Disable timeline widget  
            skyBox: false, // Disable skyBox  
            skyAtmosphere: false,// Disable skyAtmosphere  
            scene3DOnly: true,
            shadows: false,
            orderIndependentTranslucency: false, // 禁用顺序无关半透明  
            contextOptions: {
                webgl: {
                    alpha: true, // 使WebGL上下文支持透明  
                    // stencil: true, // 禁用模板缓冲区  
                    // powerPreference: 'high-performance' // 设置电源偏好  
                }

            }
            // context: context,
        });
        // viewer.scene.backgroundColor = new Cesium.Color(255, 255, 0, 0);
        viewer.scene.backgroundColor = Cesium.Color.TRANSPARENT;

         // Create a custom shader to only write to the depth buffer  
         const customShader = new Cesium.CustomShader({  
            fragmentShaderText: `  
                void main() {  
                    // Do nothing, just write to depth buffer  
                    gl_FragColor = vec4(0.0);  
                }  
            `,  
            translucent: true  
        });  
  
        // Add an invisible occluding box with the custom shader  
        const invisibleOccluder = viewer.entities.add({  
            position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883, 100),  
            box: {  
                dimensions: new Cesium.Cartesian3(100.0, 100.0, 100.0),  
                material: new Cesium.Material({  
                    fabric: {  
                        type: 'Color',  
                        uniforms: {  
                            color: new Cesium.Color(1.0, 1.0, 1.0, 0.0)  
                        }  
                    }  
                }),  
                shadows: Cesium.ShadowMode.DISABLED,  
                customShader: customShader  
            }  
        });  
  
        // Add a visible box behind the invisible occluder  
        const visibleBox = viewer.entities.add({  
            position: Cesium.Cartesian3.fromDegrees(-75.5985, 40.03883, 50),  
            box: {  
                dimensions: new Cesium.Cartesian3(50.0, 50.0, 50.0),  
                material: Cesium.Color.BLUE  
            }  
        });  
  
        // Set the viewer to focus on the entities  
        viewer.zoomTo(viewer.entities);  

    </script>
</body>

</html>

Hi there,

I’m curious what the goal of this application is. Perhaps there is a better way to achieve the effect you’re looking for.

This is a very cool and innovative feature. I plan to implement true AR effects in videos captured by drones. Typically, one would directly edit the video to incorporate AR elements, but my approach is to overlay an AR-annotated video on top of the original, merging the two into one. Currently, I am reconstructing the camera’s pose information from the drone’s flight logs, which needs to be visualized in a 3D map. Then, I will add the information where I want to augment reality in the video, generate a new video, and overlay it onto the drone footage. The effect will be similar to AR videos created with software like After Effects, and the occlusion effect is very important for the final result.

Awesome! What type of content are you rendering in CesiumJS? Is it geometry like boxes, or more models or 3D Tiles?

I think the best route to go here (if you do expect to use geometries like boxes) is to use Custom Geometry and Appearances.

I have tried using Custom Geometry & Appearances but I still can’t achieve what I need.