threeJs+光照+方块模型+控制器

最近一直在看three.js的相关资料,官网的看了,基本上是对新手很不友好的。下面是我的一个练习。
光照+控制器+模型+材质等等知识都用了一下…

效果图

由于懒得拍成视频然后转GIF图,直接用静态图了。

threeJs+光照+方块模型+控制器_第1张图片

下载项目相关

npm install three --save-dev
npm install three-trackballcontrols --save-dev

template

<template>
  <div>
    <diV id="myThree"></diV>
  </div>
</template>

import

const THREE = require("three");//主要
const TrackballControls = require("three-trackballcontrols");//控制器

vue - data

      domContainer: null, //容器
      renderer: null, //渲染器
      scene: null, //场景
      camera: null, //相机
      geometry: null, //模型
      material: null, //材质
      mesh: null, //网格

      ambientLight: null, //全局光
      directionalLight: null, //平行光
      debug: null, //灯光辅助
      control: null,
      plane: null, //平面
      texture: [//纹理图片数组
        require("../../../../assets/img/wl/1.jpg"),
        require("../../../../assets/img/wl/2.jpg"),
        require("../../../../assets/img/wl/3.jpg"),
        require("../../../../assets/img/wl/4.jpg"),
        require("../../../../assets/img/wl/5.jpg")
      ],
      /*模型信息*/
      models: {
        maxW: 100,
        maxH: 100,
        minW: 10,
        minH: 10,

        maxZCount: 6,
        minZCount: 1
      }

vue - methods

    //初始化渲染器
    initRenderer() {
      let self = this;
      self.renderer = new THREE.WebGLRenderer({ antialias: true }); //创建渲染器实例
      self.renderer.setSize(
        self.domContainer.offsetWidth,
        self.domContainer.offsetHeight
      ); //设置渲染器宽高
      self.renderer.shadowMap.enabled = true; //告诉渲染器需要阴影效果
      self.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
      self.domContainer.appendChild(self.renderer.domElement);
    },
    //初始化场景
    initScene() {
      this.scene = new THREE.Scene();
    },
    //初始化相机
    initCamera() {
      this.camera = new THREE.PerspectiveCamera(
        45,
        this.domContainer.offsetWidth / this.domContainer.offsetHeight,
        0.1,
        1000
      ); //透视相机
      this.camera.position.set(0, 150, 200);
      this.camera.lookAt(new THREE.Vector3(0, 0, 0));
    },
    onWindowResize() {
      this.camera.aspect =
      this.domContainer.offsetWidth / this.domContainer.offsetHeight;
      this.camera.updateProjectionMatrix();
      this.renderer.setSize(
        this.domContainer.offsetWidth,
        this.domContainer.offsetHeight
      );
    },
    //初始化光
    initLight() {
      let self = this;
      self.ambientLight = new THREE.AmbientLight("yellow");
      self.scene.add(self.ambientLight);

      self.directionalLight = new THREE.DirectionalLight("#FFFFFF");
      self.directionalLight.position.set(40, 60, 10);
      self.directionalLight.shadow.camera.near = 20; //产生阴影的最近距离
      self.directionalLight.shadow.camera.far = 100; //产生阴影的最远距离
      self.directionalLight.shadow.camera.left = -50; //产生阴影距离位置的最左边位置
      self.directionalLight.shadow.camera.right = 50; //最右边
      self.directionalLight.shadow.camera.top = 50; //最上边
      self.directionalLight.shadow.camera.bottom = -50; //最下面
      //这两个值决定生成阴影密度 默认512
      self.directionalLight.shadow.mapSize.height = 1024;
      self.directionalLight.shadow.mapSize.width = 1024;
      //告诉平行光需要开启阴影投射
      self.directionalLight.castShadow = true;
      self.scene.add(self.directionalLight);
    },
    //创建模型(模型,材质,网格)
    initModel() {
      let self = this;
      //立方体
      for (let x = 1; x < self.models.maxW / self.models.minW - 1; x++) {
        for (let z = 1; z < self.models.maxW / self.models.minW - 1; z++) {
          for (
            let y = 0;
            y <
            Math.floor(Math.random() * self.models.maxZCount) +
              self.models.minZCount;
            y++
          ) {
            let geometry = new THREE.CubeGeometry(
              self.models.minW,
              self.models.minW,
              self.models.minW
            );
            let r = Math.floor(Math.random() * 255);
            let g = Math.floor(Math.random() * 255);
            let b = Math.floor(Math.random() * 255);
            let a = Math.random();
            let str = "rgb(" + r + "," + g + "," + b + "," + a + ")";
            let material = new THREE.MeshBasicMaterial({
              color: str
            });
            let texture = new THREE.TextureLoader().load(
              self.texture[Math.floor(self.texture.length * Math.random())]
            ); //纹理
            material.map = texture;
            let mesh = new THREE.Mesh(geometry, material);
            mesh.position.x = -45 + x * self.models.minW;
            mesh.position.z = -45 + z * self.models.minW;
            mesh.position.y = 0 + y * self.models.minW;
            mesh.castShadow = true; //开启立方体的阴影
            self.scene.add(mesh);
          }
        }
      }

      //底部平面
      let planeGeometry = new THREE.PlaneGeometry(
        self.models.maxW,
        self.models.maxH
      );
      let planeMaterial = new THREE.MeshLambertMaterial({ color: 0xaaaaaa });

      self.plane = new THREE.Mesh(planeGeometry, planeMaterial);
      self.plane.rotation.x = -0.5 * Math.PI;
      self.plane.position.y = -5;
      self.plane.receiveShadow = true; //开启平面模型的接收阴影
      self.scene.add(self.plane);
      self.renderer.render(self.scene, self.camera);
    },
    //初始化控制器
    initControl() {
      let self = this;
      self.control = new TrackballControls(
        self.camera,
        self.renderer.domElement
      );

      // 是否开启当前的控制器 默认值为true
      self.control.enabled = true;

      // 设置当前控制器的焦点 默认为原点位置
      self.control.target = new THREE.Vector3();

      self.control.rotateSpeed = 3.0; //控制相机旋转速度
      self.control.zoomSpeed = 2; //控制相机缩放速度
      self.control.panSpeed = 0.3; //控制相机移动速度

      self.control.noRotate = false; //关闭相机旋转 默认false
      self.control.noZoom = false; //关闭相机缩放 默认false
      self.control.noPan = true; //关闭相机移动 默认false

      self.control.staticMoving = true; //关闭惯性拖拽 默认值false
      self.control.dynamicDampingFactor = 0.2; //设置惯性拖拽的阻力 默认值是0.2

      // 控制器控制相机可移动的距离焦点的最远距离和最近距离 默认值是0到无限远的距离
      self.control.minDistance = 0;
      self.control.maxDistance = 800;
    },

    animate() {
      //更新控制器
      this.control.update();
      this.renderer.render(this.scene, this.camera);

      requestAnimationFrame(this.animate);
    },
    //初始化所有
    init() {
      let self = this;
      self.domContainer = document.getElementById("myThree");
      self.initRenderer();
      self.initScene();
      self.initCamera();
      self.initLight();
      self.initModel();
      self.initControl();
      self.animate();

      window.onresize = self.onWindowResize;
    }

vue - mounted

    let self = this;
    self.init();

style

    #myThree {
      width: 100%;
      height: 800px;
    }

基本上是这样,具体可以看 我的一个练习网址
推荐一位大佬的博客

你可能感兴趣的:(threeJs)