Reputation: 1
I'm trying to use both WebGL (a Three.js 3D model) and CSS3D (HTML divs) in the same scene. The goal is to render one div behind the 3D model and another in front of it. However, currently, the model itself renders on top of both divs, causing them to be hidden or improperly layered.
Using renderOrder to control the drawing order of objects.
Assigning camera layers to differentiate between CSS3D and WebGL layers.
Explicitly setting the layers of the CSS3D objects and WebGL model using layers.set()
.
However, despite these attempts, the model is still rendered on top of the divs, and I'm unable to properly layer the divs behind and in front of the model.
function main() {
// Create WebGL & CSS3D Renderers
const renderer = new THREE.WebGLRenderer({ alpha: true });
const renderer_css3d = new CSS3DRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer_css3d.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
document.body.appendChild(renderer_css3d.domElement);
// Set CSS3D layer properties
renderer.domElement.style.position = 'absolute';
renderer.domElement.style.zIndex = '1';
renderer_css3d.domElement.style.position = 'absolute';
// Camera setup
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 200, 300);
camera.layers.enable(0);
camera.layers.enable(1);
console.log("Camera Layers:", camera.layers.mask);
// Controls
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.minDistance = 300;
controls.maxDistance = 1000;
controls.maxPolarAngle = Math.PI / 2;
// Scene setup
const scene = new THREE.Scene();
// Lighting
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(0, 3, 3);
scene.add(directionalLight);
// Group to sync WebGL & CSS3D
const group = new THREE.Group();
scene.add(group);
// 🔴 CSS3DObject (Behind Model)
const divBack = document.createElement('div');
divBack.style.width = '300px';
divBack.style.height = '150px';
divBack.innerText = 'Behind Model';
divBack.style.background = 'rgba(255, 0, 0, 0.7)';
divBack.style.color = 'white';
divBack.style.display = 'flex';
divBack.style.alignItems = 'center';
divBack.style.justifyContent = 'center';
divBack.style.fontSize = '20px';
divBack.style.borderRadius = '10px';
const css3dObjectBack = new CSS3DObject(divBack);
css3dObjectBack.position.set(0, 50, -150);
css3dObjectBack.renderOrder = 0; // Ensures it's rendered first
css3dObjectBack.layers.set(0); // CSS3D Layer
group.add(css3dObjectBack);
// 🔵 CSS3DObject (In Front of Model)
const divFront = document.createElement('div');
divFront.style.width = '300px';
divFront.style.height = '150px';
divFront.innerText = 'In Front';
divFront.style.background = 'rgba(0, 0, 255, 0.7)';
divFront.style.color = 'white';
divFront.style.display = 'flex';
divFront.style.alignItems = 'center';
divFront.style.justifyContent = 'center';
divFront.style.fontSize = '20px';
divFront.style.borderRadius = '10px';
const css3dObjectFront = new CSS3DObject(divFront);
css3dObjectFront.position.set(0, 50, 100);
css3dObjectFront.renderOrder = 2; // Ensures it's rendered last
css3dObjectFront.layers.set(0); // CSS3D Layer
group.add(css3dObjectFront);
console.log("CSS3D Object (Back) Layer:", css3dObjectBack.layers.mask);
console.log("CSS3D Object (Front) Layer:", css3dObjectFront.layers.mask);
// Load GLTF Model
const loader = new GLTFLoader();
loader.load('/models/Xbot.glb', function (gltf) {
const glbModel = gltf.scene;
glbModel.sortObjects = true;
glbModel.position.set(0, 0, 0);
glbModel.scale.set(100, 100, 100);
glbModel.renderOrder = 1; // Model should be between the divs
glbModel.layers.set(1); // WebGL Layer
group.add(glbModel);
// Set model color if available
const newColor = initialModelColor ? new THREE.Color(initialModelColor) : new THREE.Color(0xffffff);
glbModel.traverse((child) => {
if (child.isMesh && child.material) {
child.material.color = newColor;
child.material.needsUpdate = true;
}
});
// Add animation support
const mixer = new THREE.AnimationMixer(glbModel);
const animations = gltf.animations;
if (animations.length > 0) {
const walkAction = mixer.clipAction(animations[0]);
walkAction.play();
}
console.log('Model Loaded:', glbModel);
}, undefined, function (error) {
console.error('Error loading model:', error);
console.log("3D Model Layer:", glbModel ? glbModel.layers.mask : "Model not loaded");
});
// Resize handling
window.onresize = () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer_css3d.setSize(window.innerWidth, window.innerHeight);
};
// Animation loop
function render() {
controls.update();
renderer_css3d.render(scene, camera);
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
}
main();
console.log Camera Layers: 3 ///////////////////////////////////this should not be 3 i think test.php:558 CSS3D Object (Back) Layer: 1 test.php:559 CSS3D Object (Front) Layer: 1
Upvotes: 0
Views: 29