vue中使用three.js GLTFLoader

  1. 引入three.js&GLTFLoader
	import * as THREE from 'three'
	import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
	import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

在这里插入图片描述
2.初始化 创建场景、相机、渲染器、场景等等

init () {
         	// 场景
            this.scene = new THREE.Scene()
            this.clock = new THREE.Clock()
            // 创建一个远景相机
            this.camera = new THREE.PerspectiveCamera(
                75,
                window.innerWidth / window.innerHeight,
                0.1,
                100
            )
            // 渲染器
            this.renderer = new THREE.WebGLRenderer({ antialias: true })
            // 是否显示阴影
            this.renderer.shadowMapEnabled = true
            // 设置渲染氛围颜色
            this.renderer.setClearColor(new THREE.Color(0xffffff))
            // 鼠标拖拽
            this.orbitControls = new OrbitControls(
                this.camera,
                this.renderer.domElement
            )
            // 动画
            this.animationMixer = new THREE.AnimationMixer(this.scene)
            this.renderer.setSize(window.innerWidth, window.innerHeight)
            document
                .getElementById('container')
                .appendChild(this.renderer.domElement)
            window.addEventListener('resize', () => 					   this.onWindowResize())
            this.camera.position.set(5, 2, 1)
            this.getFloor()
            this.getLigt()
            this.getGLB()
            this.render()
        },
        getGLB (name) {
            this.gltfLoader = new GLTFLoader()
            let newName = name ? name : 'Soldier'
            this.gltfLoader.load( //文件加载 文件地址 我用的本地文件模拟的 vue 必须把文件放入public目录 否则文件会被编译 我是放入了public目录的model文件 说以地址为${process.env.BASE_URL}model
                `${process.env.BASE_URL}model/${newName}.glb`,
                gltf => {
                    console.log(gltf, 'gltf')
                    gltf.scene.name = newName
                    gltf.scene.position.set(0, 0, 0) //定位
                    gltf.scene.rotation.y = -Math.PI / 2 //转动 这些有点类似canvas 或者 c3的动画
                    // 模型是否否需要阴影 
                    gltf.scene.traverse(obj => {
                        obj.castShadow = true
                        obj.receiveShadow = true
                    })
                    this.scene.add(gltf.scene)
                    //遍历当前模型的动画
                    gltf.animations.forEach(i => {
                        this.state.push(i.name)
                        this[i.name] = this.animationMixer.clipAction(i)
                    })
                    // 执行第一个动画 
                    this[gltf.animations[0].name].play()
                }
            )
        },
        getFloor () {
        	//创建地板 
            let floorGeometry = new THREE.PlaneGeometry(20, 20, 20)
            let floorMaterial = new THREE.MeshPhongMaterial({
                color: 0x77F28F,
                shininess: 0
            })
            let floor = new THREE.Mesh(floorGeometry, floorMaterial)
            floor.rotation.x = -0.5 * Math.PI
            //是否接受阴影投射 (非常重要)
            floor.receiveShadow = true
            this.scene.add(floor)
        },
        render () {
            // 更新动画
            this.animationMixer.update(this.clock.getDelta())
            this.renderer.render(this.scene, this.camera)
            this.orbitControls.update()
            window.requestAnimationFrame(() => this.render())
        },

部分 这里面要注意的是模型是否有影子效果,要求如下

  • 场景开启阴影效果
this.renderer.shadowMapEnabled = true
  • 当前模型开启阴影效果
 gltf.scene.traverse(obj => {
         obj.castShadow = true
        obj.receiveShadow = true
  })
  • 有接受阴影效果的对象 当前我用的是地板
floor.receiveShadow = true
Logo

前往低代码交流专区

更多推荐