标签能否随实体一同平移或旋转?是否有更简便的实现方式?
标签随实体同步变换的最简实现方案
通用核心思路
标签不需要绑定额外的虚拟点,直接复用实体本身的世界变换矩阵计算标签屏幕坐标即可,比你当前的方案少了维护虚拟点同步变换的步骤,性能和维护成本都更低。
不同场景的具体实现
WebGL/Three.js 场景
- 直接调用实体的
getWorldPosition()方法拿到世界坐标,再通过project(camera)方法将3D世界坐标转换为2D屏幕坐标,直接更新标签的CSS/Canvas位置即可 - 示例代码片段:
// 每次实体变换或相机更新后执行 const worldPos = new THREE.Vector3() entity.getWorldPosition(worldPos) const screenPos = worldPos.project(camera) // 转换为页面像素坐标 const x = (screenPos.x * 0.5 + 0.5) * window.innerWidth const y = (-screenPos.y * 0.5 + 0.5) * window.innerHeight labelElement.style.transform = `translate(${x}px, ${y}px)`
注:如果需要标签随实体缩放,可额外计算worldPos.distanceTo(camera.position)得到距离,动态调整标签的font-size/大小即可
Cesium 数字地球场景
- 不需要额外创建点实体,直接获取当前实体的
position属性值,调用Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, position)直接得到屏幕坐标,赋值给标签DOM的位置即可 - 如果实体有模型偏移,直接用
entity.computeModelMatrix(time)拿到模型矩阵,再提取位置信息计算即可
Unity 场景
- 直接调用实体的
transform.TransformPoint(labelAnchorOffset)拿到标签锚点的世界坐标,再通过camera.WorldToScreenPoint(worldPos)转换为UI坐标,赋值给UGUI标签的anchoredPosition即可 - 不需要给实体额外加子对象,避免额外的DrawCall开销
优势对比
和你当前用虚拟点同步的方案比,上述方案的优点:
- 不需要维护虚拟点和实体的变换同步,避免不同步的BUG
- 少了虚拟点的内存和计算开销,尤其是大量实体场景下性能提升明显
- 不需要动态生成/销毁标签,可复用标签池,渲染效率更高
内容的提问来源于stack exchange,提问作者GrantFeng
相关产品推荐
相关产品推荐

