Three.js在vue中的使用(二)-动画、材质

一、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 描边高亮(推荐)

需引入 EffectComposerOutlinePass

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

相关推荐
jingling5555 分钟前
Git 常用命令指南:从入门到高效开发
前端·javascript·git·前端框架
Yanc16 分钟前
翻了vue源码 终于解决了这个在SFC中使用tsx的bug
前端·vue.js
萌萌哒草头将军23 分钟前
VoidZero 发布消息称 Vite 纪录片即将首映!🎉🎉🎉
javascript·vue.js·vite
好好好明天会更好24 分钟前
那些关于$event在vue中不得不说的事
前端·vue.js
浮桥33 分钟前
vue3渲染html数据并实现文本修改
javascript·vue.js·html
JosieBook36 分钟前
【web应用】前后端分离项目基本框架组成:Vue + Spring Boot 最佳实践指南
前端·vue.js·spring boot
子龙_42 分钟前
JS解析wav音频数据并使用wasm加速
前端·javascript·音视频开发
爱吃大橘1 小时前
到底用 `Promise.reject` 还是 `throw new Error`
前端·javascript·面试
aningxiaoxixi1 小时前
android audio 之 Engine
android·前端·javascript
码农小菲1 小时前
告别虚拟 DOM?Vue3.6 Vapor 模式的性能革命与实践
前端·javascript·vue.js