three.js标签标注、场景信息标注——系统总结,总有一款适合你

three.js标签标注、场景信息标注——系统总结,总有一款适合你

视频总结https://www.bilibili.com/video/BV1gC4y1v7EP

下面是具体的文字总结

标注技术分类在这里插入图片描述

标注效果分类

在这里插入图片描述

CSS2DRenderer渲染HTML元素

HTML元素作为标签使用,标签尺寸不随场景缩放变化

在这里插入图片描述

CSS3DRenderer渲染HTML元素

HTML元素作为标签使用,标签尺寸随场景缩放变化

在这里插入图片描述

精灵模型Sprite标注

精灵模型可以图片或canvas画布作为纹理,然后标注,可以实现类似CSS3DRenderer渲染HTML元素的效果。

默认区别在于Sprite本质上是threejs模型对象,会被其他模型物体遮挡,但是CSS3标签,本质上是HTML元素,只是叠加到canvas画布上,不是threejs物体的一部分,如果CSS3标签你想隐藏遮挡,需要手动添加代码,通过射线的方式,判断标签是否被其他模型遮挡,然后设置标签的style属性隐藏即可。

图片创建纹理对象,作为精灵Sprite材质的map属性值
在这里插入图片描述

canvas画布创建纹理对象,作为精灵Sprite材质的map属性值
在这里插入图片描述

2D标注:矩形平面网格模型

地面导航箭头(矩形平面+背景透明的颜色贴图)

在这里插入图片描述

地面指南针方向(矩形平面+背景透明的颜色贴图)

在这里插入图片描述

地图可视化,地面的波动光圈

在这里插入图片描述

3D标注:立体网格模型

智慧城市、地图场景中的热点标注(四棱锥)
在这里插入图片描述

在这里插入图片描述

火焰特效(序列帧动画或shader)

在这里插入图片描述

CSS2DRenderer(HTML元素作为标签)

下面给大家介绍一个threejs的扩展库CSS2DRenderer.js,通过CSS2DRenderer.js可以把HTML元素作为标签标注三维场景。

引入扩展库CSS2DRenderer.js

在threejs文件包目录examples/jsm/renderers/,你可以找到CSS2DRenderer.js扩展库。

threejs扩展库CSS2DRenderer.js提供了两个类CSS2渲染器CSS2DRenderer、CSS2模型对象CSS2DObject

// 引入CSS2渲染器CSS2DRenderer和CSS2模型对象CSS2DObject
import {
    CSS2DRenderer,CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
// 引入CSS2渲染器CSS2DRenderer
import {
    CSS2DRenderer } from 'three/addons/renderers/CSS2DRenderer.js';
// 引入CSS2模型对象CSS2DObject
import {
    CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';

总体思路

本节课先为大家演示标签标注最基本的内容,更多需要完善优化的的细节,可以关注后面几节课讲解。

  • 1.HTML元素创建标签
  • 2.CSS2模型对象CSS2DObject
  • 3.CSS2渲染器CSS2DRenderer
  • 4.CSS2Renderer.domElement重新定位

1. HTML元素创建标签

你可以根据需要,使用HTML、CSS代码创建你想要的标签。如果基于vue或react开发,也可以用vue或react创建的UI组件表示标签。

<div id="tag">标签内容</div>

如果你想用HTML元素作为标签标注三维场景中模型信息,就需要考虑定位的问题。比如一个模型,在代码中你可以知道它的局部坐标或世界坐标xyz,但是你并不知道渲染后在canvas画布上位置,距离web页面顶部top和左侧的像素px值。

自己写代码把世界坐标xyz,转化为像素px表示屏幕坐标,比较麻烦,不过threejs扩展库CSS2DRenderer.js可以帮助你实现坐标转化,给HTML元素标签定位,下面给大家演示如何实现。

2. CSS2模型对象CSS2DObject

// 引入CSS2模型对象CSS2DObject
import {
    CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';

通过CSS2DObject类,可以把一个HTML元素转化为一个类似threejs网格模型的对象,换句话说就是你可以把CSS2DObject当成threejs的一个模型一样去设置位置.position或添加到场景中。

const div = document.getElementById('tag');
// HTML元素转化为threejs的CSS2模型对象
const tag = new CSS2DObject(div);

你想把HTML标签标注在那个位置,你通过.position属性设置标签模型对象的xyz坐标。

tag.position.set(50,0,50);

把HTML元素对应的CSS2模型对象添加到其它模型对象或三维场景中。

scene.add(tag);
const group = new THREE.Group();
group.add(tag);

3. CSS2渲染器CSS2DRenderer

// 引入CSS2渲染器CSS2DRenderer
import {
    CSS2DRenderer } from 'three/addons/renderers/CSS2DRenderer.js';
// 创建一个CSS2渲染器CSS2DRenderer
const css2Renderer = new CSS2DRenderer();

CSS2渲染器CSS2DRenderer和WebGL渲染器WebGLRenderer虽然不同,但是有些属性和方法是相似的,可以类比记忆学习。比如.domElement.setSize().render()。可以先参考webgl渲染器写代码,然后再给大家解释其中的含义。

3.1 CSS2Renderer.render()渲染HTML标签

CSS2渲染器CSS2DRenderer和常用的WebGL渲染器WebGLRenderer一样都是渲染器,只是渲染模型对象不同,WebGLRenderer主要是渲染threejs自身的网格、点、线等模型,CSS2DRenderer用来渲染HTML元素标签对应的CSS2模型对象CSS2DObject

// 用法和webgl渲染器渲染方法类似
css2Renderer.render(scene, camera);
// renderer.render(scene, camera);

3.2 CSS2Renderer.setSize()

### 如何在 Three.js 中实现场景中对象的信息标注和动态连线效果 #### 信息标注的功能实现 为了在 Three.js 场景标注特定对象,可以利用 `THREE.TextGeometry` 或者基于 HTML 和 CSS 的 DOM 节点叠加方法。以下是两种常见的实现方式: 1. **使用 TextGeometry 创建三维文字标签** 可以创建一个带有材质的文字几何体并将其放置在目标对象附近。 ```javascript const loader = new THREE.FontLoader(); loader.load(&#39;fonts/helvetiker_regular.typeface.json&#39;, function (font) { const textGeo = new THREE.TextGeometry("Object Label", { font: font, size: 0.5, height: 0.1, curveSegments: 12, bevelEnabled: true, bevelThickness: 0.03, bevelSize: 0.02, bevelOffset: 0, bevelSegments: 5 }); const material = new THREE.MeshBasicMaterial({ color: 0xffffff }); const labelMesh = new THREE.Mesh(textGeo, material); scene.add(labelMesh); // 将标签定位到目标对象旁边 labelMesh.position.copy(targetObject.position).add(new THREE.Vector3(1, 1, 0)); })[^4]; ``` 2. **使用 CanvasRenderer 渲染二维文本覆盖** 如果希望更灵活地控制样式,可以通过 HTML 元素与 WebGL 渲染器结合的方式,在画布上层显示自定义的标注。 ```html <div id="label" style="position:absolute; pointer-events:none;"></div> ``` 在 JavaScript 中更新该元素的位置: ```javascript function updateLabelPosition(object) { const vector = object.getWorldPosition(new THREE.Vector3()); projector.unprojectVector(vector.clone().setZ(1), camera); // 投影至屏幕坐标系 const pos = vector.project(camera); document.getElementById(&#39;label&#39;).style.transform = ` translate(${pos.x * window.innerWidth / 2}px, ${-pos.y * window.innerHeight / 2}px)` } ``` #### 动态连线的效果实现 对于动态连线功能,通常采用 `THREE.Line` 来绘制线条连接两个或多个对象。具体步骤如下: 1. 定义顶点数组表示起始点和终点; 2. 使用 LineBasicMaterial 设置颜色和其他属性; 3. 构造 Line 对象加入场景; 示例代码片段展示了如何建立一条简单的直线链接两个球形物体: ```javascript const points = []; points.push(new THREE.Vector3(-5, 0, 0)); // Start point of the line points.push(new THREE.Vector3(5, 0, 0)); // End point of the line const geometry = new THREE.BufferGeometry().setFromPoints(points); const material = new THREE.LineBasicMaterial({ color: 0x00ff00 }); // Create a line and add it to the scene. const line = new THREE.Line(geometry, material); scene.add(line)[^5]; ``` 如果需要实时追踪鼠标位置并与最近的目标相连,则需引入 Raycaster 工具检测当前光标下的碰撞情况,并调整端点坐标匹配最新状态。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Threejs可视化

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值