介紹,實(shí)現(xiàn)場(chǎng)景中物體標(biāo)注標(biāo)簽信息)
系列文章目錄Three.js 快速入門教程【一】開啟你的 3D Web 開發(fā)之旅Three.js 快速入門教程【二】透視投影相機(jī)Three.js 快速入門教程【三】渲染器Three.js 快速入門教程【四】三維坐標(biāo)系Three.js 快速入門教程【五】動(dòng)畫渲染循環(huán)Three.js 快速入門教程【六】相機(jī)控件 OrbitControlsThree.js 快速入門教程【七】常見幾何體類型Three.js 快速入門教程【八】常見材質(zhì)類型Three.js 快速入門教程【九】光源類型Three.js 快速入門教程【十】常見的紋理類型Three.js 快速入門教程【十一】天空盒的多種實(shí)現(xiàn)方式Three.js 快速入門教程【十二】外部模型加載Three.js 快速入門教程【十三】外部模型加載后常見的處理操作Three.js 快速入門教程【十四】使用Stats.js監(jiān)控渲染幀率和性能優(yōu)化Three.js 快速入門教程【十五】交互神器DragControls使用詳解實(shí)現(xiàn)對(duì)物體或模型拖拽Three.js 快速入門教程【十六】調(diào)試神器 gui.js使用詳解可視化面板控制場(chǎng)景參數(shù)提高開發(fā)效率Three.js 快速入門教程【十七】射線拾取模型——射線與射線投射器Raycaster介紹Three.js 快速入門教程【十八】射線拾取模型——鼠標(biāo)點(diǎn)擊屏幕選中模型或物體Three.js 快速入門教程【十九】CSS2D渲染器介紹實(shí)現(xiàn)場(chǎng)景中物體或設(shè)備標(biāo)注標(biāo)簽信息Three.js 快速入門教程【二十】三維模型優(yōu)化實(shí)戰(zhàn)使用gltf-pipeline與Draco對(duì)模型進(jìn)行壓縮提高加載速度和流暢性文章目錄系列文章目錄一、前言二、CSS3DRendererCSS3D渲染器介紹三、CSS3DRenderer 和 CSS2DRenderer區(qū)別1. 變換支持2. 視覺效果3. 性能4. 使用場(chǎng)景5. 代碼對(duì)比四、CSS3DObjectCSS3D對(duì)象模型五、示例代碼五、CSS3DSprite CSS3D精靈模型三種渲染方式簡單總結(jié)六、總結(jié)一、前言在 Three.js 中構(gòu)建 3D 場(chǎng)景時(shí)經(jīng)常需要為場(chǎng)景中的設(shè)備或?qū)ο筇砑訕?biāo)簽標(biāo)注以提供更多的信息。在前面系列文章Three.js 快速入門教程【十九】CSS2DRendererCSS2D渲染器一文中介紹了通過CSS2DRenderer來渲染標(biāo)簽該方式有其弊端例如標(biāo)簽始終保持原來大小無法跟隨相機(jī)縮放。這個(gè)時(shí)候我們需要使用另外一種渲染方式CSS3DRendererCSS3D渲染器來生成標(biāo)簽。本文將講解如何使用CSS3DRenderer來渲染標(biāo)簽以及和CSS2DRenderer區(qū)別。二、CSS3DRendererCSS3D渲染器介紹CSS3DRenderer 是 Three.js 提供的一種渲染器它不使用 WebGL 繪制 3D 場(chǎng)景而是通過 CSS 3D 變換來渲染 HTML 元素。這意味著你可以在 3D 空間中放置普通的 HTML 內(nèi)容如文本、圖片、按鈕等并利用 Three.js 的強(qiáng)大功能控制它們的位置、旋轉(zhuǎn)和動(dòng)畫。CSS3DRenderer用法和CSS2DRenderer整體使用流程基本相同配合CSS3模型 CSS3DObject或CSS3DSprite生成標(biāo)簽。三、CSS3DRenderer 和 CSS2DRenderer區(qū)別1. 變換支持CSS3DRenderer支持完整的 3D 變換平移、旋轉(zhuǎn)、縮放元素可集成到三維空間中跟隨相機(jī)視角產(chǎn)生透視效果如近大遠(yuǎn)小、遮擋關(guān)系。CSS2DRenderer僅支持 2D 變換平面平移、旋轉(zhuǎn)元素始終面向屏幕無透視變形。2. 視覺效果CSS3DRenderer元素會(huì)隨 3D 場(chǎng)景的視角變化而動(dòng)態(tài)變形例如貼在立方體表面的 HTML 內(nèi)容在旋轉(zhuǎn)時(shí)會(huì)有正確的 3D 效果。CSS2DRenderer元素始終平鋪在屏幕上僅位置跟隨 3D 對(duì)象但保持固定方向和比例類似 HUD 標(biāo)簽。3. 性能CSS3DRenderer由于復(fù)雜的 3D 矩陣計(jì)算和瀏覽器渲染開銷性能較低尤其在元素?cái)?shù)量多時(shí)。CSS2DRenderer僅處理 2D 變換性能更高適合需要頻繁更新的場(chǎng)景。4. 使用場(chǎng)景CSS3DRenderer適用于需要 HTML 元素深度融入 3D 空間的場(chǎng)景如 3D 數(shù)據(jù)可視化、復(fù)雜 UI如可交互的 3D 面板。CSS2DRenderer適合靜態(tài)標(biāo)簽、信息提示如地圖標(biāo)記、物體名稱需跟隨 3D 對(duì)象位置但無需透視變形。5. 代碼對(duì)比代碼使用流程基本相同把名稱由2D換3D即可例如// CSS3DRendererconstcss3DRenderernewCSS3DRenderer();constcss3DObjectnewCSS3DObject(divElement);css3DObject.position.set(10,20,30);// 三維坐標(biāo)css3DObject.rotation.xMath.PI/2;// 支持繞 X/Y/Z 軸旋轉(zhuǎn)css3Renderer.render(scene,camera);// CSS2DRendererconstcss2DRenderernewCSS2DRenderer();constcss2DObjectnewCSS2DObject(divElement);css2DObject.position.set(10,20);// 僅 X/Y 坐標(biāo)Z 軸用于遮擋排序不影響位置css2DObject.rotation.zMath.PI/4;// 僅繞 Z 軸旋轉(zhuǎn)類似屏幕平面旋轉(zhuǎn)css2Renderer.render(scene,camera);//渲染四、CSS3DObjectCSS3D對(duì)象模型CSS3DObject 與CSS2DObject作用和用法類似是一個(gè)特殊的對(duì)象允許你將 HTML/CSS 元素集成到 3D 場(chǎng)景中并通過 CSS3D 變換實(shí)現(xiàn) 3D 效果。它屬于 CSS3DRenderer 的一部分與傳統(tǒng)的 WebGL 渲染器如 WebGLRenderer不同主要用于混合 HTML 內(nèi)容和 3D 場(chǎng)景創(chuàng)建 CSS3DObject// 創(chuàng)建一個(gè) HTML 元素constelementdocument.createElement(div);element.innerHTMLHello CSS3D!;element.style.backgroundColor#f00;element.style.padding20px;// 轉(zhuǎn)換為 CSS3DObjectconstcss3DObjectnewTHREE.CSS3DObject(element);// 像普通 3D 對(duì)象一樣設(shè)置位置、旋轉(zhuǎn)、縮放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);// 在動(dòng)畫循環(huán)中渲染functionanimate(){css3DRenderer.render(scene,camera);requestAnimationFrame(animate);}animate();五、示例代碼下面展示一個(gè)正方體和圓柱體分別在頭頂標(biāo)注標(biāo)簽示例import*asTHREEfromthree;import{OrbitControls}fromthree/addons/controls/OrbitControls.js;// 引入CSS3渲染器CSS3DRenderer和CSS3模型對(duì)象CSS3DObjectimport{CSS3DRenderer,CSS3DObject}fromthree/addons/renderers/CSS3DRenderer.js;// 創(chuàng)建場(chǎng)景constscenenewTHREE.Scene();scene.backgroundnewTHREE.Color(0x333333);//坐標(biāo)輔助線constaxesHelpernewTHREE.AxesHelper(500);scene.add(axesHelper);// 創(chuàng)建相機(jī)constcameranewTHREE.PerspectiveCamera(// 透視相機(jī)75,window.innerWidth/window.innerHeight,0.1,3000);camera.position.set(2,5,10);// 創(chuàng)建WebGLRenderer渲染器constrenderernewTHREE.WebGLRenderer();// 設(shè)置渲染器寬高renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);//加入點(diǎn)光源letpointLightnewTHREE.PointLight(0xffffff,15,1000,1);pointLight.position.set(3,3,3);scene.add(pointLight);/** * 創(chuàng)建一個(gè)立方體標(biāo)簽 */constboxGeometrynewTHREE.BoxGeometry(1,1,1);constboxMaterialnewTHREE.MeshLambertMaterial({color:0x1678e2});constboxMeshnewTHREE.Mesh(boxGeometry,boxMaterial);//設(shè)置立方體位置boxMesh.position.set(2,2,2);scene.add(boxMesh);// 創(chuàng)建一個(gè) HTML 元素作為標(biāo)簽constlabelElementcreateLabelElement(立方體);// 創(chuàng)建 CSS3DObject 并將標(biāo)簽元素添加到其中constlabelnewCSS3DObject(labelElement);// 設(shè)置標(biāo)簽相對(duì)于設(shè)備對(duì)象的位置label.position.set(0,1,0);//縮放標(biāo)簽label.scale.set(0.015,0.015,0.015);//標(biāo)簽添加到立方體boxMesh.add(label);/** * 創(chuàng)建一個(gè)圓柱體標(biāo)簽 */constgeometrynewTHREE.CylinderGeometry(1,1,1,32);//創(chuàng)建材質(zhì)constmaterialnewTHREE.MeshLambertMaterial({color:0xffff00});// 創(chuàng)建一個(gè)網(wǎng)格對(duì)象將幾何體和材質(zhì)組合在一起constcylinderMeshnewTHREE.Mesh(geometry,material);//設(shè)置圓柱體體位置cylinderMesh.position.set(5,2,2);//添加到場(chǎng)景中scene.add(cylinderMesh);// 創(chuàng)建一個(gè) HTML 元素作為標(biāo)簽constlabelElement2createLabelElement(圓柱體);// 創(chuàng)建 CSS3DObject 并將標(biāo)簽元素添加到其中constlabel2newCSS3DObject(labelElement2);// 設(shè)置標(biāo)簽相對(duì)于設(shè)備對(duì)象的位置label2.position.set(0,1,0);//縮放標(biāo)簽label2.scale.set(0.015,0.015,0.015);//標(biāo)簽添加到圓柱體cylinderMesh.add(label2);//創(chuàng)建一個(gè)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;//創(chuàng)建標(biāo)簽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);// 渲染循環(huán)動(dòng)畫functionanimate(){requestAnimationFrame(animate);control.update();renderer.render(scene,camera);css3Renderer.render(scene,camera);}// 執(zhí)行動(dòng)畫animate()運(yùn)行效果五、CSS3DSprite CSS3D精靈模型CSS3DSprite 屬于 CSS3DObject 的特殊類型它具備自動(dòng)朝向相機(jī)的功能這一點(diǎn)和 THREE.Sprite精靈模型 類似無論相機(jī)處于何種位置元素始終面向觀察者。除了這一點(diǎn)其他和CSS3DObject 渲染規(guī)律一樣使用方式也相同。當(dāng)一些特殊場(chǎng)景要求標(biāo)簽始終要面向攝像頭就可以使用CSS3D精靈模型。把上述示例代碼CSS3DObject 換成CSS3DSprite 觀察效果import*asTHREEfromthree;import{OrbitControls}fromthree/addons/controls/OrbitControls.js;// 引入CSS3渲染器CSS3DRenderer和CSS3模型對(duì)象CSS3DObjectimport{CSS3DRenderer,CSS3DObject,CSS3DSprite}fromthree/addons/renderers/CSS3DRenderer.js;// 創(chuàng)建場(chǎng)景constscenenewTHREE.Scene();scene.backgroundnewTHREE.Color(0x333333);//坐標(biāo)輔助線constaxesHelpernewTHREE.AxesHelper(500);scene.add(axesHelper);// 創(chuàng)建相機(jī)constcameranewTHREE.PerspectiveCamera(// 透視相機(jī)75,// 視角 角度數(shù)window.innerWidth/window.innerHeight,// 寬高比 占據(jù)屏幕0.1,// 近平面相機(jī)最近能看到物體3000// 遠(yuǎn)平面相機(jī)最遠(yuǎn)能看到物體);camera.position.set(2,5,10);// 創(chuàng)建WebGLRenderer渲染器constrenderernewTHREE.WebGLRenderer();// 設(shè)置渲染器寬高renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);//加入點(diǎn)光源letpointLightnewTHREE.PointLight(0xffffff,15,1000,1);pointLight.position.set(3,3,3);scene.add(pointLight);/** * 創(chuàng)建一個(gè)立方體標(biāo)簽 */constboxGeometrynewTHREE.BoxGeometry(1,1,1);constboxMaterialnewTHREE.MeshLambertMaterial({color:0x1678e2});constboxMeshnewTHREE.Mesh(boxGeometry,boxMaterial);//設(shè)置立方體位置boxMesh.position.set(2,2,2);scene.add(boxMesh);// 創(chuàng)建一個(gè) HTML 元素作為標(biāo)簽constlabelElementcreateLabelElement(立方體);// 創(chuàng)建 CSS3DSprite 并將標(biāo)簽元素添加到其中constlabelnewCSS3DSprite(labelElement);// 設(shè)置標(biāo)簽相對(duì)于設(shè)備對(duì)象的位置label.position.set(0,1,0);//縮放標(biāo)簽label.scale.set(0.015,0.015,0.015);//標(biāo)簽添加到立方體boxMesh.add(label);/** * 創(chuàng)建一個(gè)圓柱體標(biāo)簽 */constgeometrynewTHREE.CylinderGeometry(1,1,1,32);//創(chuàng)建材質(zhì)constmaterialnewTHREE.MeshLambertMaterial({color:0xffff00});// 創(chuàng)建一個(gè)網(wǎng)格對(duì)象將幾何體和材質(zhì)組合在一起constcylinderMeshnewTHREE.Mesh(geometry,material);//設(shè)置圓柱體體位置cylinderMesh.position.set(5,2,2);//添加到場(chǎng)景中scene.add(cylinderMesh);// 創(chuàng)建一個(gè) HTML 元素作為標(biāo)簽constlabelElement2createLabelElement(圓柱體);// 創(chuàng)建 CSS3DSprite 并將標(biāo)簽元素添加到其中constlabel2newCSS3DSprite(labelElement2);// 設(shè)置標(biāo)簽相對(duì)于設(shè)備對(duì)象的位置label2.position.set(0,1,0);//縮放標(biāo)簽label2.scale.set(0.015,0.015,0.015);//標(biāo)簽添加到圓柱體cylinderMesh.add(label2);//創(chuàng)建一個(gè)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;//創(chuàng)建標(biāo)簽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);// 渲染循環(huán)動(dòng)畫functionanimate(){requestAnimationFrame(animate);control.update();renderer.render(scene,camera);css3Renderer.render(scene,camera);}// 執(zhí)行動(dòng)畫animate()運(yùn)行效果從運(yùn)行效果可以發(fā)現(xiàn)CSS3DSprite在保持CSS3DObject原有渲染特點(diǎn)如可縮放基礎(chǔ)上改變面向方向使得標(biāo)簽始終面向攝像頭 。三種渲染方式簡單總結(jié)CSS2DRenderer :標(biāo)簽不能縮放、默認(rèn)始終面向攝像頭只能在2D平面通過代碼控制方向CSS3DObject :標(biāo)簽?zāi)芸s放、默認(rèn)保持初始方向可在3D平面通過代碼控制方向CSS3DSprite :標(biāo)簽?zāi)芸s放、默認(rèn)始終面向攝像頭可在3D平面通過代碼控制方向六、總結(jié)通過本篇文章我們介紹了在 Three.js 中使用 CSS3DRenderer 渲染標(biāo)簽方法以及和CSS2DRenderer對(duì)比。實(shí)際開發(fā)中應(yīng)根據(jù)具體使用場(chǎng)景選擇合理的渲染方式來滿足需求。更多three.js入門知識(shí)點(diǎn)請(qǐng)關(guān)注該系列教程后續(xù)的更新。