ThreeJS 基础(1)初始化

77 阅读2分钟

介绍: 主要总结threeJs在vue中的使用

安装引入

npm install three
import * as THREE from 'three';
  1. 最好确定版本号,以免three更新造成版本不兼容问题
  2. 使用轨道控制器、加载器等时,还需要另行引入

数据初始化

  1. 全局变量准备
      scene: null,
      camera: null,
      renderer: null,
      objects: null,
  1. 容器准备
    // 数据初始化
    initData() {
      this.container = this.$refs.three; //容器
    },

创建场景

Scene – three.js docs (threejs.org)

   // 创建场景
    createScene() {
      this.scene = new THREE.Scene();
      this.scene.environment =  环境贴图 ; //若该值不为null,则该纹理贴图将会被设为场景中所有物理材质的环境贴图。
    },

创建相机

  • 透视相机 PerspectiveCamera:进大远小,模拟人眼
  • 正交相机:视锥体就是一个立方体,无近大远小,永远渲染2d场景或者ui元素

设置合适的相机参数

    // 创建相机
    createCamera() {
      this.camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,  // 一般设置为canvas画布宽高比
        0.9,
        100
      );
      // 相机位置
      this.camera.position.set(0, 2, 10);     
      // 观察目标点的坐标
      this.camera.lookAt(this.scene.position);
      this.scene.add(this.camera);
    },

创建轨道控制器——控制相机

Orbit controls(轨道控制器)可以使得相机围绕目标进行轨道运动。

轨道控制器会影响lookAt的设置,注意手动修改control

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
    // 创建控制器
    createOrbitControls() {
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);
      this.controls.enableDamping = true; // 启用阻尼
      this.controls.minPolarAngle = 0.5; // 最小绕y轴角度
      this.controls.maxPolarAngle = 1.35; // 最大绕y轴角度
      this.controls.zoomSpeed = 0.3; // 放慢缩放速度
    },
    // 加载
    render() {
      this.renderer.render(this.scene, this.camera);
      this.controls && this.controls.update(); //使用控制器后,必须在加载的时候update
      requestAnimationFrame(this.render);
    },

创建灯光

  • 环境光ambient:环境光会均匀的照亮场景中所有物体,环境光不能用来投射阴影,因为它没有方向。
  • 平行光directionalLight :类似于太阳光
  • 点光源pointLight:类似于灯泡
  • 聚光灯spotlight:类似于手电筒
  

    // 添加燈光
    createLight() {
      let light1 = new THREE.DirectionalLight(0xffffff, 1); // 创建一个方向光,参数为光的颜色和强度
      light1.position.set(0, 0, 10);
      this.scene.add(light1);
    },

创建渲染器

    // 创建渲染器
    createRenderer() {
      this.renderer = new THREE.WebGL1Renderer();
      this.renderer.setSize(
        this.container.clientWidth,
        this.container.clientHeight
      );
      this.renderer.antialisa = true; // 抗锯齿
      //   this.renderer.setClearColor("pink"); // 设置画面颜色
      this.container.appendChild(this.renderer.domElement);
    },

创建网格地面

    // 创建网格地面
    createGridHelper() {
      const gridHelper = new THREE.GridHelper(10, 10); // size divisions
      this.scene.add(gridHelper);
      //   gridHelper.material.transparent = true;
      //   gridHelper.material.opacity = 0.5;
    },

创建坐标轴辅助器

    // 创建坐标轴辅助器
    createAxesHelper() {
      const axesHelper = new THREE.AxesHelper(5);
      this.scene.add(axesHelper);
    },

载入模型

载入3D模型 – three.js docs (threejs.org) GLTFLoader – three.js docs (threejs.org)

import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
   const loader = new GLTFLoader();
      loader.load(
        "path/to/model.glb",
        (gltf) => {
          console.log("模型加载完毕...")
          this.scene.add(gltf.scene);
          // 遍历模型,拿到目标子模型
          glft.scene.traverse((child) => {
          if (child.name === "door_right") {
            this.rightDoor = child;
          }
          })
        },
    
      );
  1. 加载地址写打包后的相对地址,否则可能加载不出来
  2. blender 导出的部分纹理,threejs可能无法加载出,如:颜色渐变等
  3. 载入模型后,记得根据模型调节相机参数

自定义mesh

    createMesh () {
      const box = new THREE.BoxGeometry(1, 1, 1);
      // 材质:MeshStandardMaterial标准网格材质,是基于物理渲染的,能够基于物理模型处理灯光和阴影,更接近物理世界的真实场景。
      const material = new THREE.MeshStandardMaterial({ color: 0xffff00 })
      // 物体
      const cube = new THREE.Mesh(box, material);
      cube.castShadow = true; // 设置物体的投射阴影
      this.scene.add(cube)
    },