Three.js 快速入门教程【二十一】CSS3D渲染器(CSS3DRenderer、CSS3DObject 、CSS3DSprite)介绍,实现场景中物体标注标签信息

📅 2026/8/7 22:18:00
Three.js 快速入门教程【二十一】CSS3D渲染器(CSS3DRenderer、CSS3DObject 、CSS3DSprite)介绍,实现场景中物体标注标签信息
系列文章目录Three.js 快速入门教程【一】开启你的 3D Web 开发之旅Three.js 快速入门教程【二】透视投影相机Three.js 快速入门教程【三】渲染器Three.js 快速入门教程【四】三维坐标系Three.js 快速入门教程【五】动画渲染循环Three.js 快速入门教程【六】相机控件 OrbitControlsThree.js 快速入门教程【七】常见几何体类型Three.js 快速入门教程【八】常见材质类型Three.js 快速入门教程【九】光源类型Three.js 快速入门教程【十】常见的纹理类型Three.js 快速入门教程【十一】天空盒的多种实现方式Three.js 快速入门教程【十二】外部模型加载Three.js 快速入门教程【十三】外部模型加载后常见的处理操作Three.js 快速入门教程【十四】使用Stats.js监控渲染帧率和性能优化Three.js 快速入门教程【十五】交互神器DragControls使用详解实现对物体或模型拖拽Three.js 快速入门教程【十六】调试神器 gui.js使用详解可视化面板控制场景参数提高开发效率Three.js 快速入门教程【十七】射线拾取模型——射线与射线投射器Raycaster介绍Three.js 快速入门教程【十八】射线拾取模型——鼠标点击屏幕选中模型或物体Three.js 快速入门教程【十九】CSS2D渲染器介绍实现场景中物体或设备标注标签信息Three.js 快速入门教程【二十】三维模型优化实战使用gltf-pipeline与Draco对模型进行压缩提高加载速度和流畅性文章目录系列文章目录一、前言二、CSS3DRendererCSS3D渲染器介绍三、CSS3DRenderer 和 CSS2DRenderer区别1. 变换支持2. 视觉效果3. 性能4. 使用场景5. 代码对比四、CSS3DObjectCSS3D对象模型五、示例代码五、CSS3DSprite CSS3D精灵模型三种渲染方式简单总结六、总结一、前言在 Three.js 中构建 3D 场景时经常需要为场景中的设备或对象添加标签标注以提供更多的信息。在前面系列文章Three.js 快速入门教程【十九】CSS2DRendererCSS2D渲染器一文中介绍了通过CSS2DRenderer来渲染标签该方式有其弊端例如标签始终保持原来大小无法跟随相机缩放。这个时候我们需要使用另外一种渲染方式CSS3DRendererCSS3D渲染器来生成标签。本文将讲解如何使用CSS3DRenderer来渲染标签以及和CSS2DRenderer区别。二、CSS3DRendererCSS3D渲染器介绍CSS3DRenderer 是 Three.js 提供的一种渲染器它不使用 WebGL 绘制 3D 场景而是通过 CSS 3D 变换来渲染 HTML 元素。这意味着你可以在 3D 空间中放置普通的 HTML 内容如文本、图片、按钮等并利用 Three.js 的强大功能控制它们的位置、旋转和动画。CSS3DRenderer用法和CSS2DRenderer整体使用流程基本相同配合CSS3模型 CSS3DObject或CSS3DSprite生成标签。三、CSS3DRenderer 和 CSS2DRenderer区别1. 变换支持CSS3DRenderer支持完整的 3D 变换平移、旋转、缩放元素可集成到三维空间中跟随相机视角产生透视效果如近大远小、遮挡关系。CSS2DRenderer仅支持 2D 变换平面平移、旋转元素始终面向屏幕无透视变形。2. 视觉效果CSS3DRenderer元素会随 3D 场景的视角变化而动态变形例如贴在立方体表面的 HTML 内容在旋转时会有正确的 3D 效果。CSS2DRenderer元素始终平铺在屏幕上仅位置跟随 3D 对象但保持固定方向和比例类似 HUD 标签。3. 性能CSS3DRenderer由于复杂的 3D 矩阵计算和浏览器渲染开销性能较低尤其在元素数量多时。CSS2DRenderer仅处理 2D 变换性能更高适合需要频繁更新的场景。4. 使用场景CSS3DRenderer适用于需要 HTML 元素深度融入 3D 空间的场景如 3D 数据可视化、复杂 UI如可交互的 3D 面板。CSS2DRenderer适合静态标签、信息提示如地图标记、物体名称需跟随 3D 对象位置但无需透视变形。5. 代码对比代码使用流程基本相同把名称由2D换3D即可例如// CSS3DRendererconstcss3DRenderernewCSS3DRenderer();constcss3DObjectnewCSS3DObject(divElement);css3DObject.position.set(10,20,30);// 三维坐标css3DObject.rotation.xMath.PI/2;// 支持绕 X/Y/Z 轴旋转css3Renderer.render(scene,camera);// CSS2DRendererconstcss2DRenderernewCSS2DRenderer();constcss2DObjectnewCSS2DObject(divElement);css2DObject.position.set(10,20);// 仅 X/Y 坐标Z 轴用于遮挡排序不影响位置css2DObject.rotation.zMath.PI/4;// 仅绕 Z 轴旋转类似屏幕平面旋转css2Renderer.render(scene,camera);//渲染四、CSS3DObjectCSS3D对象模型CSS3DObject 与CSS2DObject作用和用法类似是一个特殊的对象允许你将 HTML/CSS 元素集成到 3D 场景中并通过 CSS3D 变换实现 3D 效果。它属于 CSS3DRenderer 的一部分与传统的 WebGL 渲染器如 WebGLRenderer不同主要用于混合 HTML 内容和 3D 场景创建 CSS3DObject// 创建一个 HTML 元素constelementdocument.createElement(div);element.innerHTMLHello CSS3D!;element.style.backgroundColor#f00;element.style.padding20px;// 转换为 CSS3DObjectconstcss3DObjectnewTHREE.CSS3DObject(element);// 像普通 3D 对象一样设置位置、旋转、缩放css3DObject.position.set(0,0,0);css3DObject.rotation.yMath.PI/4;scene.add(css3DObject);通过CSS3DRenderer渲染CSS3DObject 需要与 CSS3DRenderer 配合使用而非 WebGLRendererconstcss3DRenderernewTHREE.CSS3DRenderer();css3DRenderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(css3DRenderer.domElement);// 在动画循环中渲染functionanimate(){css3DRenderer.render(scene,camera);requestAnimationFrame(animate);}animate();五、示例代码下面展示一个正方体和圆柱体分别在头顶标注标签示例import*asTHREEfromthree;import{OrbitControls}fromthree/addons/controls/OrbitControls.js;// 引入CSS3渲染器CSS3DRenderer和CSS3模型对象CSS3DObjectimport{CSS3DRenderer,CSS3DObject}fromthree/addons/renderers/CSS3DRenderer.js;// 创建场景constscenenewTHREE.Scene();scene.backgroundnewTHREE.Color(0x333333);//坐标辅助线constaxesHelpernewTHREE.AxesHelper(500);scene.add(axesHelper);// 创建相机constcameranewTHREE.PerspectiveCamera(// 透视相机75,window.innerWidth/window.innerHeight,0.1,3000);camera.position.set(2,5,10);// 创建WebGLRenderer渲染器constrenderernewTHREE.WebGLRenderer();// 设置渲染器宽高renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);//加入点光源letpointLightnewTHREE.PointLight(0xffffff,15,1000,1);pointLight.position.set(3,3,3);scene.add(pointLight);/** * 创建一个立方体标签 */constboxGeometrynewTHREE.BoxGeometry(1,1,1);constboxMaterialnewTHREE.MeshLambertMaterial({color:0x1678e2});constboxMeshnewTHREE.Mesh(boxGeometry,boxMaterial);//设置立方体位置boxMesh.position.set(2,2,2);scene.add(boxMesh);// 创建一个 HTML 元素作为标签constlabelElementcreateLabelElement(立方体);// 创建 CSS3DObject 并将标签元素添加到其中constlabelnewCSS3DObject(labelElement);// 设置标签相对于设备对象的位置label.position.set(0,1,0);//缩放标签label.scale.set(0.015,0.015,0.015);//标签添加到立方体boxMesh.add(label);/** * 创建一个圆柱体标签 */constgeometrynewTHREE.CylinderGeometry(1,1,1,32);//创建材质constmaterialnewTHREE.MeshLambertMaterial({color:0xffff00});// 创建一个网格对象将几何体和材质组合在一起constcylinderMeshnewTHREE.Mesh(geometry,material);//设置圆柱体体位置cylinderMesh.position.set(5,2,2);//添加到场景中scene.add(cylinderMesh);// 创建一个 HTML 元素作为标签constlabelElement2createLabelElement(圆柱体);// 创建 CSS3DObject 并将标签元素添加到其中constlabel2newCSS3DObject(labelElement2);// 设置标签相对于设备对象的位置label2.position.set(0,1,0);//缩放标签label2.scale.set(0.015,0.015,0.015);//标签添加到圆柱体cylinderMesh.add(label2);//创建一个CSS3渲染器constcss3RenderernewCSS3DRenderer();css3Renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(css3Renderer.domElement);css3Renderer.domElement.style.positionabsolute;css3Renderer.domElement.style.top0;css3Renderer.domElement.style.pointerEventsnone;//创建标签DomfunctioncreateLabelElement(text){constlabelElementdocument.createElement(div);labelElement.textContenttext;labelElement.style.backgroundColorwhite;labelElement.style.padding5px;labelElement.style.border1px solid black;labelElement.style.borderRadius5px;returnlabelElement;}// 控制器constcontrolnewOrbitControls(camera,renderer.domElement);// 渲染循环动画functionanimate(){requestAnimationFrame(animate);control.update();renderer.render(scene,camera);css3Renderer.render(scene,camera);}// 执行动画animate()运行效果五、CSS3DSprite CSS3D精灵模型CSS3DSprite 属于 CSS3DObject 的特殊类型它具备自动朝向相机的功能这一点和 THREE.Sprite精灵模型 类似无论相机处于何种位置元素始终面向观察者。除了这一点其他和CSS3DObject 渲染规律一样使用方式也相同。当一些特殊场景要求标签始终要面向摄像头就可以使用CSS3D精灵模型。把上述示例代码CSS3DObject 换成CSS3DSprite 观察效果import*asTHREEfromthree;import{OrbitControls}fromthree/addons/controls/OrbitControls.js;// 引入CSS3渲染器CSS3DRenderer和CSS3模型对象CSS3DObjectimport{CSS3DRenderer,CSS3DObject,CSS3DSprite}fromthree/addons/renderers/CSS3DRenderer.js;// 创建场景constscenenewTHREE.Scene();scene.backgroundnewTHREE.Color(0x333333);//坐标辅助线constaxesHelpernewTHREE.AxesHelper(500);scene.add(axesHelper);// 创建相机constcameranewTHREE.PerspectiveCamera(// 透视相机75,// 视角 角度数window.innerWidth/window.innerHeight,// 宽高比 占据屏幕0.1,// 近平面相机最近能看到物体3000// 远平面相机最远能看到物体);camera.position.set(2,5,10);// 创建WebGLRenderer渲染器constrenderernewTHREE.WebGLRenderer();// 设置渲染器宽高renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);//加入点光源letpointLightnewTHREE.PointLight(0xffffff,15,1000,1);pointLight.position.set(3,3,3);scene.add(pointLight);/** * 创建一个立方体标签 */constboxGeometrynewTHREE.BoxGeometry(1,1,1);constboxMaterialnewTHREE.MeshLambertMaterial({color:0x1678e2});constboxMeshnewTHREE.Mesh(boxGeometry,boxMaterial);//设置立方体位置boxMesh.position.set(2,2,2);scene.add(boxMesh);// 创建一个 HTML 元素作为标签constlabelElementcreateLabelElement(立方体);// 创建 CSS3DSprite 并将标签元素添加到其中constlabelnewCSS3DSprite(labelElement);// 设置标签相对于设备对象的位置label.position.set(0,1,0);//缩放标签label.scale.set(0.015,0.015,0.015);//标签添加到立方体boxMesh.add(label);/** * 创建一个圆柱体标签 */constgeometrynewTHREE.CylinderGeometry(1,1,1,32);//创建材质constmaterialnewTHREE.MeshLambertMaterial({color:0xffff00});// 创建一个网格对象将几何体和材质组合在一起constcylinderMeshnewTHREE.Mesh(geometry,material);//设置圆柱体体位置cylinderMesh.position.set(5,2,2);//添加到场景中scene.add(cylinderMesh);// 创建一个 HTML 元素作为标签constlabelElement2createLabelElement(圆柱体);// 创建 CSS3DSprite 并将标签元素添加到其中constlabel2newCSS3DSprite(labelElement2);// 设置标签相对于设备对象的位置label2.position.set(0,1,0);//缩放标签label2.scale.set(0.015,0.015,0.015);//标签添加到圆柱体cylinderMesh.add(label2);//创建一个CSS3渲染器constcss3RenderernewCSS3DRenderer();css3Renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(css3Renderer.domElement);css3Renderer.domElement.style.positionabsolute;css3Renderer.domElement.style.top0;css3Renderer.domElement.style.pointerEventsnone;//创建标签DomfunctioncreateLabelElement(text){constlabelElementdocument.createElement(div);labelElement.textContenttext;labelElement.style.backgroundColorwhite;labelElement.style.padding5px;labelElement.style.border1px solid black;labelElement.style.borderRadius5px;returnlabelElement;}// 控制器constcontrolnewOrbitControls(camera,renderer.domElement);// 渲染循环动画functionanimate(){requestAnimationFrame(animate);control.update();renderer.render(scene,camera);css3Renderer.render(scene,camera);}// 执行动画animate()运行效果从运行效果可以发现CSS3DSprite在保持CSS3DObject原有渲染特点如可缩放基础上改变面向方向使得标签始终面向摄像头 。三种渲染方式简单总结CSS2DRenderer :标签不能缩放、默认始终面向摄像头只能在2D平面通过代码控制方向CSS3DObject :标签能缩放、默认保持初始方向可在3D平面通过代码控制方向CSS3DSprite :标签能缩放、默认始终面向摄像头可在3D平面通过代码控制方向六、总结通过本篇文章我们介绍了在 Three.js 中使用 CSS3DRenderer 渲染标签方法以及和CSS2DRenderer对比。实际开发中应根据具体使用场景选择合理的渲染方式来满足需求。更多three.js入门知识点请关注该系列教程后续的更新。