Three.js 中的 CSS2D 和 CSS3D:展示与对比

1,047 阅读2分钟

1. 引言

简要介绍Three.js中CSS2D和CSS3D的作用和展现形式,以及两者的异同点。

2. 关于CSS2D和CSS3D

CSS2D:基于 CSS2DObjectCSS2DRenderer 实现和渲染,它将 DOM 素渲染到Three.js场景中,并使其保持相对视图的固定位置。比较适合需要实现UI元素(如信息面板、文本标签等)在3D场景中的展示。

CSS3D:基于 CSS3DObjectCSS3DRenderer 实现和渲染,它使 DOM 元素在Three.js场景中呈现3D变换的效果,可以进行3D旋转、缩放等。实现场景有:3D信息面板、3D中的网页展示、3D视频面板等。

3. 示例:基本的CSS2DObject实现

实现效果:

代码示例:

import { CSS2DRenderer, CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'// ......
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
document.body.appendChild(renderer.domElement);

// 创建一个简单的 2D 元素
const div = document.createElement('div');
div.innerHTML = "CSS2DObject Label - Cube 1";
div.style.fontSize = "30px";
const css2DObject = new THREE.CSS2DObject(div); // 🌟🌟

// 设置对象位置
css2DObject.position.set(0, 1.5, 0);
scene.add(css2DObject);

camera.position.z = 5;
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
  css2DRenderer.render(scene, camera);}
animate();

4. 示例:基本的CSS3DObject实现

实现效果:

代码示例:

import { CSS3DRenderer, CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer'// ......
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
document.body.appendChild(renderer.domElement);

// 创建一个简单的 3D 元素
const div = document.createElement('div');
div.innerHTML = "CSS3DObject Label - Cube 2";
div.style.fontSize = "30px";
const css3DObject = new THREE.CSS3DObject(div); // 🌟🌟

// 设置对象位置
css3DObject.position.set(0, 1.5, 0);
css3DObject.scale.set(0.01, 0.01, 0.01); // 🌟🌟
scene.add(css3DObject);

camera.position.z = 5;
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
  css3DRenderer.render(scene, camera); // 🌟🌟
}
animate();

4.1 关于CSS3DObject的scale问题

其中使用CSS3D的方式实现DOM元素展示时,要注意尽量加上缩放,因为默认情况下,1个单位等于1000像素,不缩放的话会显得特别大。

CSS3DObject 的尺寸问题实际上与 Three.js 的坐标系统和 DOM 元素的像素尺寸之间的关系有关:

Three.js 坐标系统:

  • Three.js 使用一个抽象的 3D 单位系统
  • 比如一个立方体设置 BoxGeometry(1, 1, 1),在场景中就是 1 个单位大小

DOM 元素:

  • DOM 元素使用像素(px)作为单位
  • 例如一个 div 宽 200px,高 100px

CSS3DObject 的转换:

  • 当我们将 DOM 元素包装成 CSS3DObject 时,这个元素会被直接放入 3D 空间
  • DOM 元素的像素尺寸会被直接解释为 3D 空间的单位
  • 所以如果你有一个 200px × 100px 的 div,它在 3D 空间中会被解释为 200 × 100 个单位大小

5. CSS2DObject 与 CSS3DObject 的对比

......暂时结束,溜了