【图片完整效果代码位于文章末】
往期文章:
【threejs教程5】threejs添加文字标注,且始终面向屏幕
前言
在threejs中我们经常需要引入外部模型文件,本文将演示如何加载外部glb模型文件,以小米su7模型为例,本文只做简单加载和车轮动画。更多功能将在后面文章中讲解。如需要模型文件资源可站内私信。
1.准备工作
1.1引入必要的库
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'
1.2解码文件
解码文件/draco/gltf文件夹位于three/examples/js/libs/draco/gltf/目录下,建议将其放在public静态目录下,防止打包时可能发生的报错。
2.加载模型
2.1创建模型和解码文件loader
const loader = new GLTFLoader()
const dracoloader = new DRACOLoader()
dracoloader.setDecoderPath('./draco/gltf/')
loader.setDRACOLoader(dracoloader)
loader.load('./model/xiaomisu7.glb', (gltf) => {
const car = gltf.scene
scene.add(car)
})
2.2添加灯光
为加载到场景的模型添加必要的灯光,我添加了十个位置的灯光,大家可以根据需要的效果自行修改。
function addLight() {
const lightPos = [
[0, 0, 10],
[0, 0, -10],
[0, 10, 0],
[0, -10, 0],
[-10, 0, 0],
[10, 0, 0],
[5, 10, 0, 0.3],
[-5, 10, 0, 0.3],
[0, 10, 5, 0.3],
[0, 10, -5, 0.3],
]
for (let [x, y, z, intensity] of lightPos) {
intensity == undefined ? 1 : intensity
const light = new THREE.DirectionalLight(0xffffff, intensity)
light.position.set(x, y, z)
scene.add(light)
}
}
2.3给汽车轮胎添加动画
这个模型中的轮胎我在blender里进行了拆解,并且命名为了“车轮xx”,所以我们可以从车的模型中找出车轮并给每个车轮添加旋转的动画。
car.traverse((child) => {
if (child.isMesh && child.name.includes('车轮')) {
function animate() {
requestAnimationFrame(animate)
child.rotation.x -= 0.03
}
animate()
}
})
3.完整效果代码如下所示
<template></template>
<script setup>
import * as THREE from 'three'
import { onMounted, ref } from 'vue'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
)
const renderer = new THREE.WebGLRenderer({ antialias: true })
const controls = new OrbitControls(camera, renderer.domElement)
onMounted(() => {
init()
})
function init() {
camera.position.set(0, 0, 5)
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
controls.update()
function animate() {
requestAnimationFrame(animate)
controls.update()
renderer.render(scene, camera)
}
animate()
addLight()
}
// 添加汽车模型
const loader = new GLTFLoader()
const dracoloader = new DRACOLoader()
dracoloader.setDecoderPath('./draco/gltf/')
loader.setDRACOLoader(dracoloader)
loader.load('./model/xiaomisu7.glb', (gltf) => {
const car = gltf.scene
scene.add(car)
console.log(car)
car.traverse((child) => {
if (child.isMesh && child.name.includes('车轮')) {
function animate() {
requestAnimationFrame(animate)
child.rotation.x -= 0.03
}
animate()
}
})
})
function addLight() {
const lightPos = [
[0, 0, 10],
[0, 0, -10],
[0, 10, 0],
[0, -10, 0],
[-10, 0, 0],
[10, 0, 0],
[5, 10, 0, 0.3],
[-5, 10, 0, 0.3],
[0, 10, 5, 0.3],
[0, 10, -5, 0.3],
]
for (let [x, y, z, intensity] of lightPos) {
intensity == undefined ? 1 : intensity
const light = new THREE.DirectionalLight(0xffffff, intensity)
light.position.set(x, y, z)
scene.add(light)
}
}
</script>
(模型文件获取来源于网络,仅作为学习交流,涉及侵权请联系)