12.具体实现-烘焙部分-动画信息配置
12.1 知识点
先搞清楚纹理里是怎么存的
在设计配置数据结构之前,得先回顾一下 VAT 纹理的存储方式。
回顾之前的的代码,纹理是按这个顺序写入的:
假设有一个模型,9500 个顶点,3 个动画(A、B、C),分别有 20、50、57 帧。纹理尺寸 2048×2048。
每个动画需要的像素数:
| 动画 | 帧数 | 像素数(帧数 × 顶点数) |
|---|---|---|
| A | 20 | 190,000 |
| B | 50 | 475,000 |
| C | 57 | 541,500 |
| 总计 | 127 | 1,206,500 |
纹理中的存储区间:
纹理宽度 2048,每行可存 2048 个像素。
| 动画 | 像素索引范围 | 行范围 | 说明 |
|---|---|---|---|
| A | 0 ~ 189,999 | 第 0 ~ 92 行 | 20帧 × 9500顶点 = 190,000像素 |
| B | 190,000 ~ 664,999 | 第 93 ~ 324 行 | 紧接动画A,50帧 × 9500顶点 = 475,000像素 |
| C | 665,000 ~ 1,206,499 | 第 325 ~ 589 行 | 紧接动画B,57帧 × 9500顶点 = 541,500像素 |
总共占用约 590 行,纹理高度 2048 行,空间充足。

纹理是连续平铺的:先写完动画 A 的所有帧,再写动画 B 的所有帧,最后写动画 C 的所有帧。
运行时需要知道什么
Shader 在运行时要从纹理里取出正确的顶点位置,需要知道:
- 当前播放的是哪个动画
- 当前播放到第几帧
- 这个动画在纹理里的起始位置
- 这个模型有多少个顶点
- 顶点坐标的 min/max(用于从 0~1 还原回原始坐标)
把这些信息整理一下,可以分成两类:
同一个模型所有动画共用的信息
这些信息对于同一个模型来说是不变的:
| 信息 | 类型 | 示例值 | 用途 |
|---|---|---|---|
| 顶点总数 | int | 9500 | 计算纹理坐标时需要知道有多少个顶点 |
| 顶点最大坐标 | int | 128 | 从归一化坐标还原回原始坐标 |
| 顶点最小坐标 | int | -64 | 从归一化坐标还原回原始坐标 |
| VAT 纹理 | Texture2D[] | 见下方说明 | 采样获取顶点位置 |
VAT 纹理说明:
- 如果动画少、帧数少,一张纹理就够用,数组长度为 1。
- 如果动画多、帧数多,超出单张纹理容量,就需要多张纹理。
- 当前示例(9500 顶点、127 帧)只占用 590 行,一张 2048×2048 纹理足够,所以数组长度为 1。
每个动画独立的信息
这些信息每个动画都不一样:
| 信息 | 类型 | 示例值 | 用途 |
|---|---|---|---|
| 动画名 | string | “Walk” | 识别是哪个动画 |
| 总帧数 | int | 50 | 控制动画播放范围 |
| 帧率 | int | 30 | 计算播放速度 |
| 像素索引起始位置 | int | 190000 | 知道从纹理的哪个位置开始读 |
| 使用的纹理索引 | int | 0 | 如果用到多张纹理,标记用哪一张 |
纹理索引说明:
- 单张纹理时,所有动画的纹理索引都是 0。
- 多张纹理时,需要记录该动画的数据存在第几张纹理里。
数据结构设计
根据上面的分析,需要创建两个类:
AnimationInfo:存储单个动画的信息
using System;
// VAT中单个动画需要的信息
// 之后我们需要利用这些信息来进行动画更新
[Serializable]
public class AnimationInfo
{
// 动画名
public string animationName;
// 总帧数
public int frameCount;
// 像素索引的起始位置
public int pixelIndex;
// 帧率
public int frameRate;
}
AnimationInfos:整个模型 VAT 的配置信息(继承ScriptableObject,方便序列化存储为资源文件)
using UnityEngine;
// VAT需要记录的信息
public class AnimationInfos : ScriptableObject
{
// 顶点总数
public int vertexCount;
// 顶点最大值坐标
public int vertexMax;
// 顶点最小值坐标
public int vertexMin;
// 烘焙的动作纹理(VAT)
public Texture2D vat_texture;
// 单个动画信息们
public AnimationInfo[] allAnimationinfo;
}
12.2 知识点代码
AnimationInfo.cs
using System;
// VAT中单个动画需要的信息
// 之后我们需要利用这些信息来进行动画更新
[Serializable]
public class AnimationInfo
{
// 动画名
public string animationName;
// 总帧数
public int frameCount;
// 像素索引的起始位置
public int pixelIndex;
// 帧率
public int frameRate;
}
AnimationInfos.cs
using UnityEngine;
// VAT需要记录的信息
public class AnimationInfos : ScriptableObject
{
// 顶点总数
public int vertexCount;
// 顶点最大值坐标
public int vertexMax;
// 顶点最小值坐标
public int vertexMin;
// 烘焙的动作纹理(VAT)
public Texture2D vat_texture;
// 单个动画信息们
public AnimationInfo[] allAnimationinfo;
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com