变形目标(Morph Targets)

概述

学习目标

  • 理解变形目标的基本概念
  • 掌握变形目标动画的创建和使用
  • 学会读取变形目标名称
  • 了解变形目标的应用场景

前置知识要求

  • 动画基础
  • 3D 开发基础
  • 资源管理基础

核心概念

什么是变形目标?

变形目标是 3D 模型中用于创建形状变化的顶点位置集合。通过混合多个变形目标,可以创建各种形状变化效果,如面部表情、肌肉变形等。

为什么需要变形目标?

  1. 面部表情:可以创建各种面部表情
  2. 形状变化:可以创建各种形状变化效果
  3. 细节动画:可以创建细节动画效果
  4. 性能优化:可以优化动画性能

变形目标的核心组件

Bevy 变形目标动画包含以下核心组件:

  • MorphTargets:变形目标集合,包含多个变形目标
  • MorphWeights:变形权重,控制变形目标的混合比例
  • AnimationClip:动画片段,包含变形目标动画数据
  • AnimationGraph:动画图,用于组织和管理变形目标动画

基础用法

变形目标动画

创建和播放变形目标动画。

源代码文件bevy/examples/animation/morph_targets.rs

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
use bevy::prelude::*;

fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut graphs: ResMut<Assets<AnimationGraph>>,
) {
// 加载包含变形目标的 GLTF 模型
let gltf_path = "models/animated/MorphStressTest.gltf";

// 加载动画片段(包含变形目标动画)
let animation_clip = asset_server.load(
GltfAssetLabel::Animation(2).from_asset(gltf_path)
);

// 创建动画图
let (graph, index) = AnimationGraph::from_clip(animation_clip);
let graph_handle = graphs.add(graph);

// 创建场景根节点
commands.spawn((
SceneRoot(
asset_server.load(GltfAssetLabel::Scene(0).from_asset(gltf_path))
),
AnimationGraphHandle(graph_handle),
AnimationPlayer::default().play(index).repeat(),
));
}

关键要点

  • 变形目标通常存储在 GLTF 模型中
  • 可以从 GLTF 文件加载变形目标动画
  • 变形目标动画使用标准的动画系统
  • 可以设置动画的重复模式

说明
变形目标动画是创建细节动画的重要工具。通过使用变形目标,可以创建各种形状变化效果,如面部表情、肌肉变形等,而不需要额外的骨骼动画。

读取变形目标名称

读取网格的变形目标名称。

源代码文件bevy/examples/animation/morph_targets.rs

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
use bevy::prelude::*;

fn name_morphs(
asset_server: Res<AssetServer>,
mut events: MessageReader<AssetEvent<Mesh>>,
meshes: Res<Assets<Mesh>>,
) {
for event in events.read() {
if let AssetEvent::<Mesh>::Added { id } = event
&& let Some(path) = asset_server.get_path(*id)
&& let Some(mesh) = meshes.get(*id)
&& let Some(names) = mesh.morph_target_names()
{
info!("Morph target names for {path:?}:");

for name in names {
info!(" {name}");
}
}
}
}

关键要点

  • 可以使用 mesh.morph_target_names() 来获取变形目标名称
  • 变形目标名称通常在 GLTF 文件中定义
  • 可以通过名称来识别和操作特定的变形目标
  • 变形目标名称对于调试和开发很有用

说明
读取变形目标名称是了解和使用变形目标的重要步骤。通过读取名称,可以识别模型中的变形目标,并在代码中引用它们。

变形目标权重

控制变形目标的混合权重。

源代码文件bevy/examples/animation/morph_targets.rs

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
use bevy::prelude::*;

fn control_morph_weights(
mut morph_weights: Query<&mut MorphWeights>,
input: Res<ButtonInput<KeyCode>>,
) {
for mut weights in &mut morph_weights {
// 设置特定变形目标的权重
if input.just_pressed(KeyCode::Key1) {
weights.set_weight(0, 1.0); // 设置第一个变形目标的权重为 1.0
}

if input.just_pressed(KeyCode::Key2) {
weights.set_weight(1, 1.0); // 设置第二个变形目标的权重为 1.0
}

// 重置所有权重
if input.just_pressed(KeyCode::Key0) {
weights.clear();
}
}
}

关键要点

  • 可以使用 MorphWeights 组件来控制变形目标权重
  • 权重值通常在 0.0 到 1.0 之间
  • 可以同时设置多个变形目标的权重
  • 权重控制变形目标的混合比例

说明
控制变形目标权重是创建变形效果的关键。通过调整权重,可以控制不同变形目标的混合比例,创建各种形状变化效果。

进阶用法

程序化创建变形目标动画

可以程序化创建变形目标动画。

源代码文件bevy/examples/animation/morph_targets.rs

关键信息

  • 可以程序化创建变形目标动画曲线
  • 可以使用 AnimatableCurve 来定义变形目标权重随时间的变化
  • 可以组合多个变形目标动画
  • 可以使用动画图来组织复杂的变形目标动画

说明
程序化创建变形目标动画是创建动态变形效果的关键。通过程序化创建动画,可以根据游戏状态动态调整变形目标,创建更加动态和交互的变形效果。

变形目标与骨骼动画结合

可以将变形目标动画与骨骼动画结合使用。

源代码文件bevy/examples/animation/morph_targets.rs

关键信息

  • 变形目标动画可以与骨骼动画同时使用
  • 变形目标通常用于细节动画,而骨骼动画用于主要动画
  • 可以创建复杂的动画组合
  • 性能考虑:变形目标会增加计算开销

说明
将变形目标动画与骨骼动画结合是创建复杂动画效果的关键。通过结合使用,可以创建更加丰富和详细的动画效果。

实际应用

在游戏开发中的应用场景

变形目标在游戏开发中有广泛的应用:

  1. 面部表情:创建角色的各种面部表情
  2. 肌肉变形:创建肌肉的变形效果
  3. 细节动画:创建细节动画效果,如布料变形
  4. 形状变化:创建各种形状变化效果

常见问题

问题 1:如何创建变形目标?

解决方案:变形目标通常在 3D 建模软件中创建,然后导出为 GLTF 格式。Bevy 支持从 GLTF 文件加载变形目标。

问题 2:如何控制变形目标的混合?

解决方案:使用 MorphWeights 组件来控制变形目标权重。可以通过动画系统或直接设置权重来控制混合。

问题 3:变形目标会影响性能吗?

解决方案:变形目标会增加计算开销,特别是当有多个变形目标时。应该合理使用变形目标,避免过度使用。

性能考虑

  1. 变形目标数量:尽量减少变形目标的数量
  2. 权重计算:优化权重计算以提高性能
  3. 动画优化:使用动画图来组织和管理变形目标动画
  4. LOD 系统:在远距离时可以减少变形目标的使用

相关资源

相关源代码文件

  • bevy/examples/animation/morph_targets.rs - 变形目标示例

官方文档链接

进一步学习建议

  • 学习动画基础,了解动画系统的基本使用
  • 学习 3D 开发,了解如何加载和使用 3D 模型
  • 学习动画进阶,了解动画图和动画混合

索引返回上级目录