three.js(安装,创建场景,添加模型)

143 阅读2分钟

three.js官网 threejs.org/

1 在项目中使用 npm方式 npm install --save three

2 创建场景--在场景中添加相机,轨道控制器,灯光,渲染器.

<template>
    <div id="container"></div>
</template>
<script>
    import * as THREE from 'three';
    import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
    let scene, camera, renderer, controls, mesh,css2Renderer;
    export default {
        mounted() {
            this.init();
         },
        methods:{
            //可以根据需要对init方法进行拆分
            init(){
                scene = new THREE.Scene();
                const element = document.getElementById("container");
                const width = element.clientWidth; // 窗口宽度
                const height = element.clientHeight; // 窗口高度
                const k = width / height; // 窗口宽高比
                camera = new THREE.PerspectiveCamera(35, k, 0.1, 10000);
                camera.position.set(20, 20, 500); // 设置相机位置
                camera.lookAt(new THREE.Vector3(10, 40, 0)); // 设置相机方向
                scene.add(camera);
                // 环境光
                const ambientLight = new THREE.AmbientLight(0x404040, 0.1); // 环境光
                scene.add(ambientLight); // 将环境光添加到场景
                const spotLight = new THREE.SpotLight(0xffffff); // 创建聚光灯
                spotLight.position.set(50, 50, 50);
                spotLight.castShadow = true;
                scene.add(spotLight);
                controls = new OrbitControls(camera, renderer.domElement);
                // 使动画循环使用时阻尼或自转 意思是否有惯性
                controls.enableDamping = true;
                //动态阻尼系数 就是鼠标拖拽旋转灵敏度
                //controls.dampingFactor = 0.25;
                //是否可以缩放
                // controls.enableZoom = false;
                //是否自动旋转
                controls.autoRotate = false;
                //设置相机距离原点的最远距离
                controls.minDistance = 200;
                //设置相机距离原点的最远距离
                controls.maxDistance = 10000;
                //是否开启右键拖拽
                controls.enablePan = true;
                const element = document.getElementById("container");
                renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
                renderer.setSize(element.clientWidth, element.clientHeight); // 设置渲染区域尺寸
                renderer.domElement.id = "canvas"
                renderer.shadowMap.enabled = true; // 显示阴影
                renderer.shadowMap.type = THREE.PCFSoftShadowMap;
                renderer.setClearColor("transparent", 0); // 设置背景颜色
                element.appendChild(renderer.domElement);
                renderer.domElement.addEventListener("click",this.handleClick)
            },
            render() {
              controls.update()
              renderer.render(scene, camera);
              requestAnimationFrame(this.render);
            },
        }
    }
</script>

3 在场景中添加模型--场景中添加fbx和glb格式的模型

<script>
import { GLTFLoader, GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'
 export default{
       methods:{
            loadModelByUrL(url) {
              // 创建 FBXLoader 实例
              let fileType = this.getFileType(url) //获取文件类型
              let loader
              if (fileType) {
                if (fileType.toUpperCase() === 'FBX') {
                  loader = new FBXLoader()
                  loader.load(url, (object) => this.handleFBXModel(object as THREE.Group))
                } else if (fileType.toUpperCase() === 'GLB') {
                  loader = new GLTFLoader()
                  loader.load(url, (data) => this.handleGLTFModel(data))
                }
              }
            },
            getFileType(url) {
              const filename = url.split('/').pop() // 获取 URL 最后的部分,即文件名
              const extension = filename && filename.slice(-3) // 获取文件名最后三个字符作为扩展名
              return extension
            },
            handleFBXModel(model) {//添加fbx模型并为模型设置颜色
              let childModels = []
              model.traverse((child) => {
                // 可以选择存储子对象的名称,或者整个THREE.Object3D对象
                  if (child instanceof THREE.Mesh) {
                    const materials = child.material
                    if (Array.isArray(materials)) {
                      // 处理 material 数组的情况
                      materials.forEach((material) => {
                        if ('color' in material) {
                          // 首先也确保material有color属性
                          ;(material as THREE.Material & { color: THREE.Color }).color.set(0xffffff)
                          material.needsUpdate = true
                          childModels.push(material)
                        }
                      })
                    } else {
                      // 处理单个 material 的情况
                      if ('color' in materials) {
                        ;(materials as THREE.Material & { color: THREE.Color }).color.set(0xffffff)
                        materials.needsUpdate = true
                      }
                    }
                  }
              })
              scene.add(model)
              this.render()
            },
            handleGLTFModel(gltf) {
              let model = gltf.scene
              scene.add(model)
              this.render()
            }
        } 
  }
</script>