Hello fellow engineers!
I’m currently working on masking between CSS3D Renderer and WebGL Renderer~
After reading some previous post, Since I’m not using react, I try to learn this example approach =>
So far I’ve realised a few ways to do this, but since I’m going to have a lot of objects, I’d like to use method 2
- Use projective lines to determine if there are any objects blocking and if there are, just make the CSS hidden.
- Place a flat model of the same size and rotation in the place of the CSS3DObject, and use blending mode.
Here’s how I’m currently creating my CSS3DObject:
import * as THREE from '../js/three/build/three.module.js';
import { CSS3DRenderer, CSS3DObject } from '../js/three/examples/jsm/renderers/CSS3DRendererLocal.js';
export class CSSrender {
constructor(main) {
this.main = main;
this.scene = main.scene;
this.sceneCSS = main.sceneCSS; // This should be the CSS3D scene
this.camera = main.camera;
this.renderer = main.renderer;
this.CSSrenderer = main.CSSrenderer;
this.LD = main.Loadings;
this.Dom = [];
this.raycaster = new THREE.Raycaster();
}
init() {
this.CSSrenderer.setSize(innerWidth, innerHeight);
this.CSSrenderer.domElement.style.position = 'absolute';
this.CSSrenderer.domElement.style.top = '0px';
$(this.CSSrenderer.domElement).addClass("canvasCSS3D");
$(document.body).prepend(this.CSSrenderer.domElement);
this.addHtmlDom_getHtml(
"labels_03", //obj.name
{ x: -1, y: 1, z: 2 }, //obj.pos
0.05,//scale
45,//obj.deg
'.pinkVendor',//dom (querySelect)
);
}
addHtmlDom_getHtml(objName, pos, scl, degrees, querySelect) {
const Div = document.querySelector(querySelect);
const divHTML = Div.outerHTML; // Get the content of the div element
// Use DOMParser to convert HTML strings into DOM elements!
const parser = new DOMParser();
const parsedHTML = parser.parseFromString(divHTML, 'text/html');
const position = new THREE.Vector3(pos.x, pos.y, pos.z);
const label = new CSS3DObject(parsedHTML.body.firstChild);
label.name = objName;
label.position.copy(position);
const radians = (degrees * Math.PI) / 180;// Convert degrees to radians
label.rotation.y = radians;
label.scale.set(scl, scl, scl);
this.sceneCSS.add(label);
this.Dom.push({
cssObj: label,
cssDom: parsedHTML.body.firstChild
});
// Create a mesh with the same shape as the CSS3DObject.
// const geometry = new THREE.PlaneGeometry(Div.offsetWidth * scl, Div.offsetHeight * scl);
const geometry = new THREE.PlaneGeometry(50, 50);
const material = new THREE.MeshLambertMaterial({
color: 0xffffff,
transparent: true,
blending: THREE.NoBlending,
opacity: 0,
});
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(pos.x, pos.y, pos.z);
mesh.rotation.y = radians;
this.scene.add(mesh);
}
}
My main.js related way to create rendering :
class ThreeScene {
constructor() {
this.scene = new THREE.Scene();
this.renderer = new THREE.WebGLRenderer();
this.CSSrenderer = new CSS3DRenderer();
// this.CSSrenderer.alpha = true; // 設置為 true
this.sceneCSS = new THREE.Scene();
//......
}
async init() {
await this.Loadings.init();
this.createScene();
this.creatSkybox();
this.createLights();
/* 創造Render */
this.createRenderer();
this.CSSrender.init();
this.createFloor();
this.Camera.init();
this.scene.add(this.camera);
this.Buildings.init();
}
update() {
this.Camera.update();
this.Buildings.update();
this.controls.update();
this.creatSkyboxUpdate();
}
createScene() {
}
creatSkybox() {
}
creatSkyboxUpdate() {
}
drawSky() {
}
createFloor() {
}
createOcean() {
}
OceanUpdate() {
}
createLights() {
}
createRenderer() {
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.renderer.setClearColor(new THREE.Color("0xFFD1A4", 0.5));
this.renderer.alpha = true;
this.renderer.shadowMap.enabled = true;
// Check if it's a mobile device, if so, leave the PixelRatio setting alone.
if (!window.matchMedia("(pointer: coarse)").matches) {
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
this.renderer.antialias = true;
} else {
// this.renderer.shadowMap.type = THREE.BasicShadowMap;
this.renderer.setPixelRatio(1);
this.renderer.shadowMap.type = THREE.PCFShadowMap;
}
$(this.renderer.domElement).addClass("canvas3D");
$(document.body).prepend(this.renderer.domElement);
}
onWindowResize(that) {
}
}
window.addEventListener('load', function () {
const app = new ThreeScene();
app.init();
animate();
function animate() {
requestAnimationFrame(animate);
app.update();
if (app.Render.finalComposer) {
app.Render.finalComposer.render(app.scene,app.camera);
app.CSSrenderer.render(app.sceneCSS, app.camera);
}
}
});
Despite these efforts, I’m still not achieving the desired occlusion effect. is that because I might be missing something or the way I think is wrong?
Thank you for your assistance!