threejs学习2-点光源-webgl_lights_pointlights

18 阅读1分钟
<template>
  <view class="content">
    <view id="webgl" class="content"></view>
  </view>
</template>

<script>
import { PointLight } from "../component/pointLight";
export default {
  data() {
    return {};
  },
  mounted() {
    const dom = document.getElementById("webgl");
    const canvas = new PointLight(dom);
    console.log("canvas", canvas);
  },
};
</script>

<style>
.content {
  height: 750rpx;
  width: 100%;
  margin: 0 auto;
}
</style>

把three抽离成class

import * as THREE from "three";
import { OBJLoader } from "three/addons/loaders/OBJLoader.js";
export class PointLight {
  constructor(dom) {
    this.dom = dom;
    this.camera = null;
    this.scene = null;
    this.object = null;
    this.light1 = null;
    this.light2 = null;
    this.light3 = null;
    this.light4 = null;
    this.clock = new THREE.Clock();
    this.init();
    this.animate();
  }

  init() {
    this.camera = new THREE.PerspectiveCamera(
      50,
      this.dom.offsetWidth / this.dom.offsetHeight,
      1,
      1000
    );
    this.camera.position.set(0, 0, 100);

    this.scene = new THREE.Scene();

    const loader = new OBJLoader();
    // 这里使用箭头函数就不需要先定义this
    loader.load("../static/WaltHead.obj", (obj) => {
      this.object = obj;
      // scale 物体的局部缩放。默认值是Vector3( 1, 1, 1 )
      // multiplyScalar 将该向量与传入值相乘
      this.object.scale.multiplyScalar(0.5);
      this.object.position.y = -30;
      this.scene.add(this.object);
    });

    // 灯光
    const sphere = new THREE.SphereGeometry(0.5, 16, 8);
    this.light1 = new THREE.PointLight(0xff0040, 400);
    this.light1.add(
      new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({ color: 0xff0040 }))
    );
    this.scene.add(this.light1);

    this.light2 = new THREE.PointLight(0x0040ff, 400);
    this.light2.add(
      new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({ color: 0x0040ff }))
    );
    this.scene.add(this.light2);

    this.light3 = new THREE.PointLight(0x80ff80, 400);
    this.light3.add(
      new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({ color: 0x80ff80 }))
    );
    this.scene.add(this.light3);

    this.light4 = new THREE.PointLight(0xffaa00, 400);
    this.light4.add(
      new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({ color: 0xffaa00 }))
    );
    this.scene.add(this.light4);

    // 点灯辅助线 和 坐标辅助
    const pointLightHelper1 = new THREE.PointLightHelper(this.light1, 1);
    const pointLightHelper2 = new THREE.PointLightHelper(this.light2, 1);
    const pointLightHelper3 = new THREE.PointLightHelper(this.light3, 1);
    const pointLightHelper4 = new THREE.PointLightHelper(this.light4, 1);
    const axesHelper = new THREE.AxesHelper(50);
    this.scene.add(axesHelper);
    this.scene.add(pointLightHelper1);
    this.scene.add(pointLightHelper2);
    this.scene.add(pointLightHelper3);
    this.scene.add(pointLightHelper4);

    // 渲染
    this.renderer = new THREE.WebGLRenderer({ antialias: true });
    this.renderer.setSize(this.dom.offsetWidth, this.dom.offsetHeight);
    this.dom.appendChild(this.renderer.domElement);
  }

  animate() {
    // 注意这里需要绑定this
    requestAnimationFrame(this.animate.bind(this));

    this.render();
  }

  render() {
    const time = Date.now() * 0.0005;
    const delta = this.clock.getDelta();

    if (this.object) this.object.rotation.y -= 0.5 * delta;

    this.light1.position.x = Math.sin(time * 0.7) * 30;
    this.light1.position.y = Math.cos(time * 0.5) * 40;
    this.light1.position.z = Math.cos(time * 0.3) * 30;

    this.light2.position.x = Math.cos(time * 0.3) * 30;
    this.light2.position.y = Math.sin(time * 0.5) * 40;
    this.light2.position.z = Math.sin(time * 0.7) * 30;

    this.light3.position.x = Math.sin(time * 0.7) * 30;
    this.light3.position.y = Math.cos(time * 0.3) * 40;
    this.light3.position.z = Math.sin(time * 0.5) * 30;

    this.light4.position.x = Math.sin(time * 0.3) * 30;
    this.light4.position.y = Math.cos(time * 0.7) * 40;
    this.light4.position.z = Math.sin(time * 0.5) * 30;

    this.renderer.render(this.scene, this.camera);
  }
}