安装插件
快速开始
转换Animator类型的动画模型
先将要转换的模型拖入Hierarchy,此处演示的模型可在插件的Demo文件夹下找到:Packages/Animation2Vat/Demo/Mesh/Animator/Dancing_Twerk.fbx
- 将Animator类型的蒙皮文件拖入到Hierarchy窗口
- 将Animator Asset 赋值给 Animator Components

通过 windows ➜ SineStudio ➜ Animation2Vat,打开Animation2Vat窗口

- 修改 Animation Type 为 Animator
- 将 Animator蒙皮对象拖入TargetObject (注意,Animator组件一定要挂载在TargetObject对象上)
- 点击Export VAT 按钮

最终会在 Assets/VatOutput文件夹中,生成对应的Mesh,Texture,Material和Prefab文件,并自动在场景中实例化了对应的Prefab.
- 生成的Mesh,Texture,Material和Prefab文件.
- 实例化的Vat Prefab 对象.

播放动画
经过上一个步骤,我们的场景中应该已经有了一个 Vat对象,选中这个对象,让我们聚焦挂载在它上面的VatPlayer组件
- 选中Vat对象
- 拖动挂载在它上面的VatPlayer组件中Time属性,此时可以观察到动画正随着Time的改变而改变
当勾选了Play On Awake 选项时,运行游戏,就会自动播放动画.

转换Animation类型的动画
先将要转换的模型拖入Hierarchy,此处演示的模型可在插件的Demo文件夹下找到:Packages/Animation2Vat/Demo/Mesh/Animation/Hip_Hop_Dancing.fbx
- 将Animation类型的蒙皮文件拖入到Hierarchy窗口
- 将 Animation蒙皮对象拖入TargetObject (注意,Animation组件一定要挂载在TargetObject对象上)

- 修改 Animation Type 为 Animation
- 点击Export VAT 按钮

最终会在 Assets/VatOutput文件夹中,生成对应的Mesh,Texture,Material和Prefab文件,并自动在场景中实例化了对应的Prefab.
- 生成的Mesh,Texture,Material和Prefab文件.
- 实例化的Vat Prefab 对象.

转换Alembic类型的动画
先将要转换的模型拖入Hierarchy,此处演示的模型可在插件的Demo文件夹下找到:Packages/Animation2Vat/Demo/Mesh/Animation/AlembicDemo.abc
- 将Alembic类型的蒙皮文件拖入到Hierarchy窗口
- 将 Alembic对象拖入TargetObject

- 修改 Animation Type 为 Alembic
- 点击Export VAT 按钮

最终会在 Assets/VatOutput文件夹中,生成对应的Mesh,Texture,Material和Prefab文件,并自动在场景中实例化了对应的Prefab.
- 生成的Mesh,Texture,Material和Prefab文件.
- 实例化的Vat Prefab 对象.

如何与Timeline相结合
方法1 : 使用Activation Track 控制Vat播放 (更简单)
- 确认你的Vat对象勾选了 Play On Awake

- 将对象拖入Timeline,使用Activation Track,并设定好 Active 的时机,此时运行游戏查看效果

方法2 : 使用Animation Track 控制Vat的Time值(更灵活)
- 确认你的Vat对象的VatPlayer组件取消勾选 Player On Awake 和 Loop

将对象拖入Timeline,使用 Animation Track,在动画中录制好Time值的变化,此时运行游戏查看效果

组件详解
Animation2Vat 窗口

Animation Type : 选择动画类型
Animation
Animator
Alembic
Exprot Normal Map : 导出法线贴图开关
Normal Map Format : 法线贴图压缩格式
RGB24 : 体积大,兼容性好
ASTC4x4 : 体积小,移动端游戏使用这个
DXT1 Crunched : 体积小,PC游戏使用这个
Texture Save Path : 贴图存储路径,Position贴图和Normal贴图都会存储在这个路径中
Export First Frame Mesh : 导出第一帧网格开关
Mesh Save Path : 网格存储路径,导出的第一帧网格将会存储在这里
Export Material : 导出材质开关,打开后将会自动创建材质球,并将贴图赋值到材质球上
Material Save Path : 材质存储路径,导出的材质将会存储在这里
Export Prefab : 导出预制体开关,打开后将自动创建预制体,并配置好Mesh,Material,VatPlayer
Prefab Save Path : 预制体存储位置,导出的预制体将存储在这里
Animation Line Count : 这将决定导出贴图时,将Animation拆分成多少行(下图展示了同一个模型,导出4行和导出8行时的Position贴图效果)

Capture Frame Rate : 采样帧率,通常12帧的效果已经非常好了
Target Object : 目标对象,将需要转换的对象拖入
Exprot Vat : 导出 Vat 的按钮
VatPlayer组件

- Play On Awake : 勾选时,会在游戏运行时自动播放动画.
- Loop : 勾选时,动画会自动循环.不勾选,动画在播放完毕后将停在最后一帧.
- Duration Time : 持续时间.
- Time : 控制当前动画播放到哪一帧 (范围0-1)
- Offset : 贴图采样偏移, 解决贴图过滤模式导致的顶点数据错误问题,更多详情请看 顶点炸裂
着色器
AnimMapLit
Animation2Vat自带了一个基于URP14的Lit修改而来的Shader. (Shader Path : Universal Render Pipeline/AnimMap_Lit)
它与URP的Lit基本相同,只是在Lit的基础上,增加了 Animation Map的选项

- Animation Map : 输入 VAT Position 贴图
- Animation Normal Map : 输入 VAT Normal 贴图
- Animation Length : 当前播放帧 (范围 0-100)
- Animation Line Count : 动画拆分行数,需要与贴图中的动画行数保持一致
编写自定义着色器
Shader
伪代码如下
......
#include "Packages/xyz.sinestudio.animation2vat/Shader/HLSL/AnimMapCommon.hlsl" //导入采样代码
......
// 声明需要用到的贴图和属性
CBUFFER_START(UnityPerMaterial)
......
half4 _AnimMap_TexelSize;
half _AnimLength;
uint _lineCount;
......
CBUFFER_END
TEXTURE2D(_AnimMap); SAMPLER(sampler_AnimMap);
TEXTURE2D(_AnimNormalMap); SAMPLER(sampler_AnimNormalMap);
struct Attributes
{
......
uint vertexID : SV_VertexID; // 添加VertexID 用于后续采样贴图
......
};
Varyings LitPassVertex(Attributes input)
{
......
float3 pos, nm;
SampleVat(input.vertexID, input.positionOS.xyz, pos, nm);
......
VertexPositionInputs vertexInput = GetVertexPositionInputs(pos.xyz);
......
VertexNormalInputs normalInput = GetVertexNormalInputs(nm, input.tangentOS);
......
}Shader Graph
AmplifyShaderEditor
常见问题
顶点炸裂

为了达到更好的过渡效果,贴图的过滤模式我们使用 Bilinear,因此可能会采样到异常的顶点位置.
当遇到这个问题时,我们只需要调整 VatPlayer组件的Offset值,直到问题消失即可
