一、Three.js 动画原理与实现
1. 基本原理
Three.js 的动画系统基于 关键帧(Keyframe) 和 时间轴(AnimationClip) 实现:
THREE.AnimationMixer
:管理多个动画片段的播放器THREE.AnimationClip
:表示一个动画片段(如行走、跳跃)THREE.AnimationAction
:表示当前正在播放的动画动作
2. 加载模型并播放动画(GLTF)
js
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
const loader = new GLTFLoader()
loader.load('/models/RobotExpressive.glb', (gltf) => {
const model = gltf.scene
scene.add(model)
// 初始化动画混合器
const mixer = new THREE.AnimationMixer(model)
const clips = gltf.animations
if (clips.length > 0) {
const action = mixer.clipAction(clips[0])
action.play()
}
// 在渲染循环中更新动画
function animate(time) {
requestAnimationFrame(animate)
const delta = clock.getDelta()
mixer.update(delta) // 更新动画状态
renderer.render(scene, camera)
}
animate()
})
3. 多动画切换控制
js
const idle = mixer.clipAction(clips.find(c => c.name === 'Idle'))
const walk = mixer.clipAction(clips.find(c => c.name === 'Walk'))
idle.play()
walk.fadeIn(0.5).play() // 淡入淡出切换
二、高亮原理与实现
1. 高亮方式对比
方式 | 原理 | 优点 | 缺点 |
---|---|---|---|
修改材质颜色 | 改变物体材质颜色 | 简单快速 | 不支持复杂效果 |
使用 OutlinePass | 后期处理添加描边 | 效果美观 | 性能消耗大 |
射线检测 + 自定义着色器 | 使用 Shader 实现实时高亮 | 灵活高效 | 开发难度高 |
2. 方法一:修改材质颜色(简单)
js
function highlightObject(obj) {
obj.material.emissive = new THREE.Color(0xff0000)
}
3. 方法二:使用 OutlinePass
描边高亮(推荐)
需引入 EffectComposer
和 OutlinePass
:
bash
npm install three/examples/js/postprocessing/EffectComposer
npm install three/examples/js/postprocessing/OutlinePass
js
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'
import { OutlinePass } from 'three/addons/postprocessing/OutlinePass.js'
// 创建后期处理
const composer = new EffectComposer(renderer)
composer.addPass(new RenderPass(scene, camera))
const outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera)
outlinePass.visibleEdgeColor.set('#ff0000') // 高亮颜色
composer.addPass(outlinePass)
// 设置要高亮的对象
let selectedObject = null
raycaster.intersectObjects(model.children, true).forEach(intersect => {
selectedObject = intersect.object
outlinePass.selectedObjects = [selectedObject]
})
三、材质原理与常见类型
1. 材质基础概念
材质决定了物体如何与光照交互,Three.js 提供了多种材质类型:
材质类型 | 特点 | 是否受光照影响 | 推荐场景 |
---|---|---|---|
MeshBasicMaterial |
固定颜色,不受光照影响 | 否 | UI、静态模型 |
MeshLambertMaterial |
漫反射光照模型 | 是 | 简单光照模拟 |
MeshPhongMaterial |
高光反射,更真实 | 是 | 金属、塑料等 |
MeshStandardMaterial |
PBR 渲染,物理真实 | 是 | 高质量展示 |
MeshPhysicalMaterial |
扩展版 Standard,支持透明度和粗糙度 | 是 | 车漆、玻璃等高级材质 |
MeshToonMaterial |
卡通风格渲染 | 是 | 动漫风格项目 |
2. 示例:更换材质
js
const material = new THREE.MeshStandardMaterial({
color: 0x666666,
metalness: 0.7,
roughness: 0.2
})
mesh.material = material
3. 使用纹理贴图
js
const textureLoader = new THREE.TextureLoader()
const map = textureLoader.load('/textures/metal.jpg')
material.map = map
material.needsUpdate = true