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入门知识点请关注该系列教程后续的更新。

相关新闻

Scalastyle实战案例:修复10个常见的Scala代码风格问题

Scalastyle实战案例:修复10个常见的Scala代码风格问题

Scalastyle实战案例:修复10个常见的Scala代码风格问题 【免费下载链接】scalastyle scalastyle 项目地址: https://gitcode.com/gh_mirrors/sc/scalastyle Scalastyle是一款强大的Scala代码静态分析工具,能够帮助开发者自动检测和修复代码风格问题…

2026/10/31 5:23:52 阅读更多 →
No-Consolation vs 传统PE加载器:为什么内存内联执行更安全高效?

No-Consolation vs 传统PE加载器:为什么内存内联执行更安全高效?

No-Consolation vs 传统PE加载器:为什么内存内联执行更安全高效? 【免费下载链接】No-Consolation A BOF that runs unmanaged PEs inline 项目地址: https://gitcode.com/gh_mirrors/no/No-Consolation No-Consolation 是一款创新的 Beacon Ob…

2026/11/2 16:00:21 阅读更多 →
Pencil Project EPZ文件格式深度解析:架构设计与性能优化最佳实践

Pencil Project EPZ文件格式深度解析:架构设计与性能优化最佳实践

Pencil Project EPZ文件格式深度解析:架构设计与性能优化最佳实践 【免费下载链接】pencil The Pencil Projects unique mission is to build a free and opensource tool for making diagrams and GUI prototyping that everyone can use. 项目地址: https://gi…

2026/11/3 5:33:38 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/3 1:09:25 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/2 10:46:11 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/2 10:47:40 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/3 2:27:21 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/2 10:46:31 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/2 10:46:26 阅读更多 →

日新闻

周新闻

月新闻