three.js给模型添加标签三种方式对比(矩形平面,精灵图,CSS2DObject)

three.js给模型添加标签三种方式对比(矩形平面,精灵图,CSS2DObject)

vue3实现,代码如下

代码

<template>
  <div class="app">
    <div ref="canvesRef" class="canvas-wrap"></div>
  </div>
</template>

<script setup>
import {
    ref, onMounted } from "vue";
import * as THREE from "three";
import {
    OrbitControls } from "three/addons/controls/OrbitControls.js";
import {
   
  CSS2DRenderer,
  CSS2DObject,
} from "three/addons/renderers/CSS2DRenderer.js";

const canvesRef = ref(null);
const canvasWidth = window.innerWidth;
const canvasHeight = window.innerHeight;

// 场景
const scene = new THREE.Scene();
// 模型
for (let i = 0; i < 3; i++) {
   
  const geometry = new THREE.BoxGeometry(40, 40, 40);
  const material = new THREE.MeshBasicMaterial({
   
    color: 0x00ffff,
  });
  const mesh = new THREE.Mesh(geometry, material);
  mesh.position.set(i * 70, 0, 0);
  scene.add(mesh);
}
// 相机
const camera = new THREE.PerspectiveCamera(
  75,
  canvasWidth / canvasHeight,
  0.1,
  3000
);
camera.position.set(200, 200, 200);
camera.lookAt(0, 0, 0);

// 坐标辅助对象
const axesHelper = new THREE.AxesHelper(200);
scene.add(axesHelper);

// 渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(canvasWidth, canvasHeight);

// 1.使用矩形平面实现标签
const planeGeometry = new THREE.PlaneGeometry(40, 20);
const texLoader = new THREE.TextureLoader();
const tex = texLoader.load("../src/assets/img/icon.png");
const planeMaterial = new THREE.MeshBasicMaterial({
   
  // 设置纹理贴图:Texture对象作为材质map属性的属性值
  map: tex, //map表示材质的颜色贴图属性
  side: THREE.DoubleSide,
});
const meshP = new THREE.Mesh(planeGeometry, planeMaterial);
meshP.position.set(0, 60, 0);
scene.add(meshP);
// 2.使用精灵图
const spriteMaterial = new THREE.SpriteMaterial({
   
  color: 0x00ff00, //设置颜色
  map: tex,
});
const sprite = new THREE.Sprite(spriteMaterial);
sprite.position.set(70, 60, 0);
sprite.scale.set(40, 20, 1);
scene.add(sprite);

// 3.CSS2DObject
const textDiv = document.createElement("div");
textDiv.className = "label";
textDiv.textContent = "Earth";
textDiv.style.backgroundColor = "transparent";
textDiv.style.color = "#fff";

const textLabel = new CSS2DObject(textDiv);
textLabel.position.set(140, 60, 0);
scene.add(textLabel);


const labelRenderer = new CSS2DRenderer();
labelRenderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.domElement.style.position = "absolute";
labelRenderer.domElement.style.top = "0px";
console.log(labelRenderer.domElement);
document.body.appendChild(labelRenderer.domElement);

// 动画渲染循环
function animate() {
   
  renderer.render(scene, camera);
  labelRenderer.render(scene, camera);

  requestAnimationFrame(animate);
}
animate();
// 相机轨道控制器
const cameraControls = new OrbitControls(camera, labelRenderer.domElement);
cameraControls.target.set(0, 0, 0); // 与相机的lookat保持一致
cameraControls.maxPolarAngle = Math.PI / 2; // 相机不能进入地下

onMounted(() => {
   
  canvesRef.value.appendChild(renderer.domElement);
});
</script>

<style lang="scss" scoped>
.app {
   
  position: relative;
}
</style>

效果如下

  1. 正前方观察在这里插入图片描述

  2. 相机位观察(右上角)在这里插入图片描述

  3. 右后方观察
    在这里插入图片描述

  4. 缩小在这里插入图片描述

总结

  1. 矩形平面方向不会改变,另外两种一直面向屏幕
  2. CSS2模型对象CSS2DObject不会缩小
  3. Spirte没有几何体,需要通过sprite.scale定义矩形精灵的长和宽。

最近更新

  1. TCP协议是安全的吗?

    2024-01-03 16:56:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-03 16:56:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-03 16:56:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-03 16:56:02       18 阅读

热门阅读

  1. docker 安装rabbitmq

    2024-01-03 16:56:02       27 阅读
  2. Clickhouse SQL字符串相关

    2024-01-03 16:56:02       41 阅读
  3. Linux文件和目录管理命令---- cp 命令

    2024-01-03 16:56:02       39 阅读
  4. sql执行顺序

    2024-01-03 16:56:02       38 阅读
  5. 【docker】linux部署docker

    2024-01-03 16:56:02       40 阅读