I am encountering an issue with a 3D model of an arm that I want to be transparent yet still occlude a watch model behind it. While I have successfully managed to render the arm with transparency, it fails to occlude the watch as intended.
Reproduction steps
The arm model should be transparent to the viewer and, at the same time, should prevent the watch model from being visible where it is positioned behind the arm.
While the arm model is transparent, it does not occlude the watch model behind it. The watch is fully visible as if there's no arm model occluding it.
Code
async function initializeThreeJS() {
return new Promise<void>((resolve, reject) => {
// Initialize Three.js
scene = new THREE.Scene();
const aspect = video.videoWidth / video.videoHeight;
const frustumSize = 10; // You can adjust this value to zoom in or out
const width = frustumSize * aspect;
const height = frustumSize;
// Add the lights
//const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
//scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(1, 1, 1);
scene.add(directionalLight);
camera = new THREE.OrthographicCamera(
width / -2, width / 2,
height / 2, height / -2,
1, 1000
);
renderer = new THREE.WebGLRenderer({ canvas: canvasElement3D, antialias: true, alpha: true });
// Add HDR
const pmremGenerator = new THREE.PMREMGenerator(renderer);
pmremGenerator.compileEquirectangularShader();
new RGBELoader()
.load('assets/hdr/environment.hdr', (texture) => {
const envMap = pmremGenerator.fromEquirectangular(texture).texture;
scene.environment = envMap;
texture.dispose();
pmremGenerator.dispose();
});
// Position the camera
camera.position.z = 5;
camera.updateProjectionMatrix();
const loader = new GLTFLoader();
let modelsLoaded = 0; // Counter for loaded models
// Function to check if all models are loaded
const checkAllModelsLoaded = () => {
modelsLoaded++;
if (modelsLoaded === 2) { // Check if both models are loaded
resolve(); // Resolve the Promise if both models are loaded
}
};
loader.load('assets/left_arm.glb', (gltf) => {
gltf.scene.traverse((child) => {
if (child instanceof THREE.Mesh) {
// Set a new MeshBasicMaterial
const newMaterial = new THREE.MeshBasicMaterial({
color: 0x00ff00,
transparent: true,
opacity: 0.0,
depthWrite: true,
colorWrite: false,
});
child.material = newMaterial;
child.renderOrder = 1; // Render first, occludes the watch
}
});
meshLeftArm = gltf.scene;
scene.add(meshLeftArm);
checkAllModelsLoaded(); // Increment and check if all models are loaded
}, undefined, (error) => {
console.error('Error loading left_arm model:', error);
reject(error); // Reject the Promise in case of an error
});
loader.load('assets/gold_casio_watch.glb', (gltf) => {
gltf.scene.traverse((child) => {
if (child instanceof THREE.Mesh) {
child.renderOrder = 2; // Render after the arm
}
});
meshGoldWatch = gltf.scene;
scene.add(meshGoldWatch);
checkAllModelsLoaded(); // Increment and check if all models are loaded
}, undefined, (error) => {
console.error('Error loading gold_casio_watch model:', error);
reject(error); // Reject the Promise in case of an error
});
});
}
Description
I am encountering an issue with a 3D model of an arm that I want to be transparent yet still occlude a watch model behind it. While I have successfully managed to render the arm with transparency, it fails to occlude the watch as intended.
Reproduction steps
The arm model should be transparent to the viewer and, at the same time, should prevent the watch model from being visible where it is positioned behind the arm.
While the arm model is transparent, it does not occlude the watch model behind it. The watch is fully visible as if there's no arm model occluding it.
Code
Live example
I can't show you a live example sadly
Screenshots
No response
Version
r157
Device
Desktop
Browser
Chrome
OS
Windows