文章数量
36
访客量
4952
访问量
9817

threejs使用pointsMaterial实现点云数据动态加载

阅读量:1368
更新时间:2023-01-23 11:01:50

效果预览:效果预览
源码下载:关注公众号【RMRF】,回复【three1】可获取源码

一、安装

npm install three

二、App.vue

<template>
  <div id="container"></div>
</template>
<script>
import * as THREE from "three"
import Stats from "three/examples/jsm/libs/stats.module.js"
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"
export default {
  data() {
    return {
      scene: null,
      camera: null,
      renderer: null,
      stats: null,
      pointsCloud: null,
      bufferGeometry: null,
      positions: [],
      colors: [],
      num: 0,
      timer: null
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    // 初始化
    init() {
      const el = document.getElementById("container")
      this.initScene()
      this.initCamera()
      this.initRenderer(el)
      this.initOrbitControls()
      this.initAxesHelper()
      this.initCube()
      this.initStats(el)
      this.render()

    },
    // 场景
    initScene() {
      this.scene = new THREE.Scene()
      this.scene.background = new THREE.Color(0x000000)
    },
    // 相机
    initCamera() {
      this.camera = new THREE.PerspectiveCamera(
        45, window.innerWidth / window.innerHeight, 1, 5000
      )
      this.camera.position.set(1000, 0, -2000)
    },
    // 渲染器
    initRenderer(el) {
      this.renderer = new THREE.WebGLRenderer({
        antialias: true,
      })
      this.renderer.setClearColor(0xeeeeee, 1.0)
      this.renderer.setSize(window.innerWidth, window.innerHeight)
      el.appendChild(this.renderer.domElement)
    },
    // 缩放
    initOrbitControls() {
      let controls = new OrbitControls(this.camera, this.renderer.domElement)
      controls.addEventListener("change", this.render)
    },
    // 坐标轴
    initAxesHelper() {
      const axes = new THREE.AxesHelper(2000)
      this.scene.add(axes)
    },
    // 正方体
    initCube() {
      const material = new THREE.PointsMaterial({
        size: 1,
        vertexColors: true,
      })
      this.bufferGeometry = new THREE.BufferGeometry()
      this.pointsCloud = new THREE.Points()
      this.pointsCloud.material = material
      this.scene.add(this.pointsCloud)
      this.timer = setInterval(() => {
        this.initCubeData()
      }, 1)
    },
    initCubeData() {
      if (this.num > 1000000) {
        clearInterval(this.timer)
        return
      }
      this.num = this.num + 1
      const n = 1000
      const n2 = n / 2
      let x = Math.random() * n - n2
      let y = Math.random() * n - n2
      let z = Math.random() * n - n2
      let vx = x / n + 0.5
      let vy = y / n + 0.5
      let vz = z / n + 0.5
      this.colors.push(vx, vy, vz)
      this.positions.push(x, y, z)
      this.bufferGeometry.setAttribute(
        "position",
        new THREE.Float32BufferAttribute(this.positions, 3)
      )
      this.bufferGeometry.setAttribute(
        "color",
        new THREE.Float32BufferAttribute(this.colors, 3)
      )
      this.pointsCloud.geometry = this.bufferGeometry
      this.render()
    },
    // 性能
    initStats(el) {
      this.stats = new Stats()
      el.appendChild(this.stats.dom)
      this.requestAnimationFrame()
    },
    requestAnimationFrame() {
      this.stats.update();
      requestAnimationFrame(this.requestAnimationFrame);
    },
    // 渲染
    render() {
      this.renderer.render(this.scene, this.camera)
    },
  }
}
</script>
<style>
* {
  padding: 0px;
  margin: 0px;
}
</style>