Chapter 80: Animation Compression, Retargeting, and Runtime Streaming
动画系统到这一章已经从骨架、混合、物理交互和 GPU skinning 走到运行时资产管理层。一个角色动作在屏幕上稳定播放,既依赖 pose 求值公式,也依赖压缩格式、骨架映射、数据加载、缓存策略、解码预算和质量验证。读完本章后,读者应能追踪一段动画 clip 从离线 keyframe 数据进入运行时 pose buffer 的路径,判断压缩误差来自曲线、骨架映射、采样频率还是 streaming 策略,并能用固定检查顺序复盘角色动作质量问题。
本章贯穿材料是一段 2 秒、60 FPS、75 个关节的跑步动画。原始导出数据包含 root translation、每个关节的 rotation track、少量 scale track、脚步事件曲线和一个上半身 additive 修正曲线。运行时目标是在同一帧内让主角高质量播放,让远处 NPC 使用更低采样率和更低更新频率,同时把同一动作迁移到身高、手臂长度和骨骼命名略有差异的角色上。
这个贯穿材料会反复暴露同一类工程矛盾:动作数据越完整,内存和带宽压力越大;压缩越强,接触点、手部姿态和 root motion 越容易产生偏差;retarget 越自动化,越依赖基础姿态、链映射和约束验证;streaming 越细,调度和解码同步越复杂。动画系统的质量判断需要同时看数据格式、误差指标、骨架语义、运行时缓存和最终视觉结果。
行业资料可以提供边界参照。Khronos 的 glTF 2.0 specification 把 animation 描述成 channel 与 sampler 的组合,sampler 连接时间戳、输出值和插值算法,channel 指向 translation、rotation、scale 或 morph target weights。Unreal Engine 的 Animation Compression 文档把压缩目标落到 animation sequence 的文件大小、内存成本和可接受质量损失;IK Rig Retargeting 文档把 retarget 的核心放到 chain、retarget pose、pelvis 和 IK 约束;Animation Budget Allocator 文档展示了多角色场景中按固定 CPU 预算动态降低 skeletal mesh 更新成本的思路。这些资料在本章中只作为工程边界,正文重点是建立可迁移的判断路径。
80.1 Keyframe Data and Compression Targets
动画压缩的输入是轨道化的时间序列。一个 skeletal clip 可以拆成多条 track:root 的位移 track、各关节的旋转 track、少量缩放 track、材质或控制参数 curve、morph weight track,以及事件时间点。运行时采样时,动画系统按当前时间在每条 track 上取值,得到 local pose,再沿骨骼层级更新 global pose,最后生成 skinning 所需的 matrix palette 或 dual quaternion palette。压缩处理的对象就是这些 track,而运行时质量取决于解码后的 track 是否仍能产生稳定的 local pose、global pose 和最终网格变形。
贯穿材料中的跑步动画如果按 60 FPS 原始存储,2 秒会产生 120 个采样点。75 个关节中,大部分关节只有 rotation track;root 额外有 translation;少数道具或夸张动画可能包含 scale。粗略估算时,单个 quaternion 用 4 个 32 位浮点数,单个 translation 用 3 个 32 位浮点数。只存旋转就已经接近 75 * 120 * 16 字节,未计入时间戳、曲线、事件、对齐和容器开销。真实项目中的动作库可能包含数千段 clip,压缩目标自然会从单个文件尺寸扩展到运行时内存、cache 带宽、解码成本和 streaming 粒度。
压缩目标需要按运行时路径拆开。磁盘文件尺寸决定包体和下载成本;常驻内存决定同一时间可保留多少 clip;解码带宽决定 pose evaluation job 每帧可处理多少角色;随机访问能力决定状态机跳转、倒放、seek 和网络同步的响应成本;误差阈值决定角色是否出现脚底滑动、手指抖动、武器偏移或面部表情偏差。把这些目标混成一个“压缩率”指标会掩盖真实瓶颈。主角近景动作通常给更严的误差阈值,远处 NPC 可以给更高压缩率和更低更新频率。
下面的图描述本章贯穿材料在运行时的核心路径。图中每个节点都是质量或性能观察点,压缩问题、retarget 问题和 streaming 问题会在不同节点表现成不同症状。
这条路径的第一个判断是“数据在哪个阶段已经失真”。如果压缩前后的 local pose 已经不同,问题集中在量化、关键帧删减或曲线拟合。如果 local pose 正确,迁移到目标骨架后手脚位置偏移,问题集中在 retarget pose、chain 映射、比例缩放或 IK 约束。如果 pose 正确但运行时偶发卡顿,问题集中在 stream cache 未命中、解码粒度过大、任务调度或内存预算。如果 CPU pose 结果正确而网格变形异常,问题转回上一章的 matrix palette、joint index、weight 和 GPU buffer 绑定。
压缩目标还要区分 track 类型。rotation track 对人体姿态贡献最大,通常需要保留关节旋转连续性和 quaternion 归一化;translation track 对 root motion、脚步位移和道具挂点贡献明显,需要在角色尺度下评估误差;scale track 在普通 humanoid 动作中较少,但在卡通拉伸、面部 rig 和特效骨骼中可能决定造型;curve track 可能驱动脚步事件、IK 权重、表情权重和 gameplay 参数,压缩后需要验证阈值穿越时机。工程上常见的稳定做法是按用途给 track 分组,再分配不同 codec、位宽、误差阈值和 streaming 优先级。
压缩前的离线分析应先做 track classification。静态 track 可以存成一个常量;缓慢变化 track 可以降低 key 数量或位宽;高频 track 需要保留更多样本;接触点相关 track 需要单独观察全局空间误差;事件和 gameplay curve 需要保护阈值穿越点。这样处理后,压缩系统面对的对象从“整段 clip”变成“具有不同风险等级的 track 集合”。这一步决定后续量化和曲线拟合的搜索空间,也决定 runtime streaming 的 chunk 组织方式。
80.2 Quantization, Curve Fitting, and Error Metrics
量化、曲线拟合和关键帧删减是动画压缩的三类核心动作。量化把浮点轨道值映射到有限位宽的整数表示;曲线拟合用较少参数近似原始采样曲线;关键帧删减删除对重建结果贡献较小的样本。三者都会改变解码结果,因此每一步都要绑定误差指标。没有误差指标的压缩只是在减少字节数,无法证明动作质量仍在预算内。
量化首先需要定义值域。translation 可以按 track 或 clip 统计最小值与最大值,再用 10 位、12 位或 16 位表示归一化值。rotation 常用 quaternion,但 quaternion 有归一化约束,q 和 -q 表示同一旋转。稳定编码通常会统一半球方向、丢弃一个可恢复分量或使用最小三分量编码,然后在解码后恢复并归一化。scale 轨道需要额外谨慎,因为 scale 会直接影响子节点空间,非均匀 scale 还会放大 skinning 和法线变换问题。
量化误差在骨骼层级中会传播。肩部 0.5 度的角度误差,在手腕位置上可能表现成数厘米偏移;手指末端同样角度误差的视觉风险可能更低,除非角色近景握持道具。root translation 的 1 厘米误差可能造成脚底滑动;面部表情曲线的 0.02 权重误差在远景不可见,在特写中可能改变嘴角轮廓。误差预算需要按关节、角色距离、动作类型和镜头用途分配。
曲线拟合适合处理连续变化轨道。线性拟合保存端点并在中间插值;Hermite 或 cubic 曲线保存切线或附加参数;关键帧删减通常会尝试删除某个 key,再重建曲线并计算误差。曲线拟合的收益来自删除冗余 key,风险来自高频动作被平滑。跑步动画的脚部摆动、膝盖伸屈、手臂快速摆动和 root 速度变化都可能包含高频信息;idle 动作、呼吸动作和长时间保持姿态的骨骼更适合 aggressive key reduction。
误差指标需要从 local 空间提升到视觉空间。local rotation error 只看单个关节;global joint position error 会沿骨骼链更新后比较关节位置;skinned vertex error 会把 pose 误差投射到网格顶点;contact error 会检查脚底、手掌、武器挂点或视线目标在关键帧附近是否偏离。动画压缩的质量验收通常以 global joint position error 和任务特定误差为主,local 误差只能作为快速筛选指标。
下面的伪代码展示一个离线压缩器如何用误差阈值搜索压缩参数。它省略了具体 codec,只保留判断路径:先压缩,后按采样时间重建 pose,再把误差映射到全局关节位置和接触点。
// Pseudocode: offline compression candidate evaluation.
CompressionResult EvaluateCandidate(
const RawClip& rawClip,
const Skeleton& skeleton,
const CompressionSettings& settings,
const ErrorThresholds& thresholds)
{
CompressedClip encoded = CompressTracks(rawClip, settings);
float maxJointError = 0.0f;
float maxContactError = 0.0f;
for (float time : BuildValidationTimes(rawClip.duration, thresholds.sampleRate)) {
LocalPose rawLocal = SampleRaw(rawClip, time);
LocalPose decodedLocal = DecodeCompressed(encoded, time);
GlobalPose rawGlobal = BuildGlobalPose(skeleton, rawLocal);
GlobalPose decodedGlobal = BuildGlobalPose(skeleton, decodedLocal);
maxJointError = Max(maxJointError, MeasureJointPositionError(rawGlobal, decodedGlobal));
maxContactError = Max(maxContactError, MeasureContactPointError(rawGlobal, decodedGlobal));
}
return { encoded.byteSize, maxJointError, maxContactError };
}
这段伪代码的关键点是误差采样频率。只在原始 keyframe 时间上验证,可能漏掉插值段中间的峰值误差;只用固定 30 FPS 验证,可能漏掉 60 FPS 输入中的快速运动;只看最大误差,可能掩盖长时间轻微滑动。稳定压缩流程会同时记录最大误差、均方误差、接触窗口误差和关键骨骼误差,并把失败样本回写到调试报告中,供动画师或工具链调整阈值。
误差阈值还要按最终用途分级。第一人称手臂、第三人称主角、过场动画、面部表情、普通 NPC 和远处 crowd 的容忍范围不同。工程配置可以把 clip 标为 hero、cinematic、gameplay、background 或 crowd,再由压缩器读取 profile。profile 在这里是压缩策略入口,会改变位宽、曲线拟合强度、contact bone 列表、事件曲线保护策略和 stream priority。
80.3 Retargeting Across Skeletons
Retargeting 是把源骨架上的动作迁移到目标骨架上的过程。它解决的工程问题是“动作语义复用”:同一段跑步、攻击或交互动作可以作用到不同身高、比例、命名和层级的角色上。retarget 输入包括源 skeleton、目标 skeleton、源 clip、retarget pose、chain mapping、比例策略、root motion 策略和可选 IK 约束;输出是目标 skeleton 上可采样的 pose 或新 clip。
最基础的 retarget 依赖关节对应关系。源骨架可能叫 upper_arm_l,目标骨架可能叫 LeftArm;源手臂两段骨骼,目标手臂可能有扭转骨;源角色 A-pose,目标角色 T-pose;源腿长较短,目标腿长较长。逐个 bone 名称匹配很容易在这些差异下失败,现代工具更倾向使用 chain 语义。Unreal 的 IK Retargeting 文档也把 limbs 与 appendages 定义成 source 和 target 两侧的 retarget chains,并允许不同骨骼数量的 arm chain 进行迁移。工程判断应先看“语义链是否对应”,再看单个 bone 的旋转偏差。
retarget pose 是迁移质量的基准面。源角色和目标角色在参考姿态中如果肩膀外展角不同,直接复制旋转会让目标手臂持续偏高或偏低;如果髋部朝向和局部轴不一致,root motion 和腿部摆动会产生横向偏移。retarget pose 的作用是让源骨架和目标骨架在一个共同语义姿态下对齐,后续动作增量才能按相近含义解释。Unity 的 animation import 面板会把 retargeting quality report 和骨长、默认旋转、层级差异等警告暴露给用户,这类警告说明转换后的动作可能偏离源动作。
比例差异需要单独处理 root 和 limbs。源角色一步跨出 0.8 米,目标角色腿长更长时,可以按目标腿长或角色高度缩放步幅;如果原样复制 root translation,目标脚步可能显得短促;如果全局按身高缩放,手部交互点可能偏离道具。合理策略通常会把 root motion、pelvis、spine、limb end effector 和 twist bone 分开处理。root 决定角色在世界中的运动,pelvis 决定身体重心,limb end effector 决定手脚接触,twist bone 决定变形分布。
IK 约束用于修正接触点和目标点。跑步动画中,脚底落地窗口需要保持稳定;持枪动画中,双手需要围绕武器对齐;攀爬动画中,手掌需要贴到横杆。纯 FK retarget 会按层级传播旋转,目标骨架比例变化后末端位置自然偏移。IK 约束可以在 retarget 后把 foot、hand 或 look-at target 拉回目标位置,但它也会改变膝盖、肘部和脊柱姿态。工程上应把 IK 视为接触修正层,并通过 pole vector、chain length、weight curve 和 LOD 阈值控制成本。
retarget 的质量验证要看动作语义,不只看骨骼数值。跑步 clip 的验证点包括:脚底落地窗口是否稳定,膝盖朝向是否自然,pelvis 是否上下跳变,root velocity 是否连续,手臂摆动是否穿过身体,武器或道具挂点是否漂移,镜头近景中的肩颈线是否异常。源骨架和目标骨架可以有不同局部旋转值,只要末端接触、重心、轮廓和时间节奏保持在目标角色可接受范围内,retarget 就完成了工程目标。
一个可复用的 retarget 排查顺序如下。先确认 source clip 在源骨架上播放正确,排除导入和压缩问题;再确认 source 与 target 的 retarget pose 对齐,尤其是肩、髋、手腕、脚踝和 pelvis;然后检查 chain mapping,保证 limb、spine、neck、finger 和 root 语义对应;接着比较 root motion 缩放与脚步接触窗口;最后打开 IK 或接触修正,观察它修复了哪些末端误差,又引入了哪些中段姿态变化。这个顺序可以防止把基础姿态错误误判成 IK 参数错误。
80.4 Animation Streaming and Memory Budget
Animation streaming 处理的是动作库规模问题。一个开放世界或多人动作游戏可能有主角动作、NPC 动作、武器动作、表情动作、过场动画、交互动作和 crowd 动作。一次关卡运行不需要把所有 clip 解码到内存,但状态机切换、网络同步和镜头切换又要求动作能在短时间内可用。streaming 系统的任务是把压缩 clip 按 chunk 组织,按优先级加载,按预算缓存,并让解码任务在帧时间内完成。
运行时内存预算至少包含四层。第一层是压缩数据缓存,也就是 stream cache 中已经加载的 chunk。第二层是解码临时数据,例如当前帧或未来几帧需要的 track block。第三层是 pose buffer,包括当前 pose、上一帧 pose、混合 pose、additive pose 和 retarget 中间 pose。第四层是 GPU skinning 资源,例如 matrix palette buffer、joint texture 或 compute skinning 输出 buffer。压缩率只影响第一层和部分第二层,角色数量和状态机复杂度会放大第三层和第四层。
chunk 粒度决定 streaming 行为。按整段 clip 加载实现简单,但状态机只用到前半秒动作时会浪费内存;按固定时间片切分可以减少峰值内存,但随机 seek 和跨 chunk 插值需要额外边界样本;按 track 分块可以只加载重要骨骼或高 LOD 轨道,但调度和解码器更复杂。实际系统常用折中方案:clip header 常驻,metadata 常驻,关键事件和 root motion 曲线高优先级,压缩 track 数据按时间块或 track group 懒加载。
解码成本需要与任务系统配合。动画更新通常分成 clip sampling、blend tree evaluation、retarget、IK、global pose build 和 skinning 上传。压缩格式如果随机访问成本高,状态机跳转时会触发长时间解码;如果解码只能串行执行,多个角色同帧切换动作会造成 CPU 峰值;如果解码结果无法复用,多个 NPC 播放同一 clip 会重复消耗 CPU。运行时设计应让相同 clip 的压缩块可共享,让解码任务可批量调度,让远处角色使用降频更新或 pose 复用。
动画预算并不只等于内存预算。多角色场景中,CPU 上的 skeletal mesh ticking、pose blending、retarget 和 IK 都会占用帧时间。Unreal 的 Animation Budget Allocator 展示了一种预算思路:固定 animation processing 的 CPU 时间预算,再按角色显著性动态降低更新频率、停止部分 ticking 或在更新之间插值。这个思路可以迁移到自研引擎:近处主角和交互对象保持完整更新,远处 NPC 降低采样率或隔帧更新,crowd 使用共享 pose 或低骨骼 LOD。
streaming 和压缩格式之间存在直接耦合。高压缩率格式可能需要读取较长时间窗口才能重建某一帧,这会削弱随机访问;每个 chunk 独立存储会增加边界开销,但能提升状态机跳转稳定性;曲线拟合如果跨越 chunk 边界,需要在边界保存额外控制点;事件曲线如果随普通 track 懒加载,gameplay 逻辑可能在 clip 尚未完整加载时错过触发点。因此,动作系统一般会把 event、root motion summary、duration、loop 点和 sync marker 放入轻量 metadata,并优先加载。
一个可执行的内存预算表可以按角色 LOD 组织。主角 LOD0 常驻当前状态机相关 clip、完整骨骼 track、完整事件曲线和高质量 retarget;近处 NPC LOD1 常驻当前 clip 与下一个候选 clip,降低部分手指和面部 track 精度;远处 NPC LOD2 加载低频 track 或共享 crowd clip;极远处 LOD3 使用简化骨架、预烘焙姿态或 vertex animation impostor。每级 LOD 都要明确压缩数据、解码频率、pose buffer 数量和 GPU palette 上传频率。
当运行时出现动作卡顿,排查顺序应先看 stream cache 命中,再看解码任务耗时,然后看 pose evaluation job 排队,最后看 GPU buffer 上传同步。视觉上“一次状态切换时卡一下”常对应 chunk 未预取或解码峰值;“大量 NPC 同时抖动”常对应预算降频策略缺少插值或 pose 复用错误;“主角动作稳定但远处角色跳帧”可能是 LOD 策略有意降低更新频率,需要检查它是否符合镜头距离和 gameplay 需求。
80.5 Runtime Animation Quality Checklist
运行时动画质量检查需要把压缩、retarget、streaming 和最终渲染分层。稳定流程是先固定输入,再逐层打开系统。用同一段跑步 clip 做 A/B:原始未压缩 clip 播放在源骨架上,压缩后 clip 播放在源骨架上,压缩后 clip retarget 到目标骨架上,最后把结果放入真实状态机、streaming 和 LOD 策略中。每一步只改变一个变量,才能定位误差来源。
第一层检查压缩误差。把 raw pose 与 decoded pose 在同一 skeleton、同一时间点比较,记录 local rotation error、global joint position error、contact point error 和 root motion delta。脚底滑动优先看 root translation、foot joint global position 和 contact window;手部抖动优先看 clavicle、upper arm、forearm、hand 的旋转误差传播;表情异常优先看 curve quantization 和 morph weight 阈值。压缩器输出的最大误差样本需要能反向定位到 clip、track、time 和 bone。
第二层检查 retarget 误差。把 decoded source pose 与 target pose 同时显示,确认 retarget pose、chain mapping、pelvis、root motion scale 和 IK goal。常见症状有肩膀外张、脚底悬空、膝盖翻转、手部偏离道具、root motion 过长或过短。每个症状都要回到链语义和基础姿态。只调 IK weight 可能暂时拉回末端位置,但基础 pose 或 chain mapping 错误会继续在其他动作中出现。
第三层检查采样频率与状态机。低采样率会让快速动作丢掉峰值,状态机 transition 会在两个 pose 之间混合,additive layer 会叠加额外旋转,sync marker 会决定步态周期对齐。跑步动画的检查点是左右脚落地时间、root velocity 曲线、blend tree speed 参数和 transition duration。压缩单独播放合格,放入状态机后脚步滑动,常见原因是 root motion、sync marker 或 transition 采样点没有对齐。
第四层检查 streaming 和预算策略。打开真实角色数量,记录 clip chunk 请求、cache miss、decode job 时间、animation job 队列长度和每级 LOD 的更新频率。远处角色降频更新时需要插值或 motion smoothing;主角切换动作时需要预取下一段 clip 的 header 和前几个 chunk;网络角色需要保证回滚或重放窗口内的 clip 数据可用。预算策略的质量目标是优先保护近处、交互中和镜头焦点角色的动作连续性。
第五层检查 GPU skinning 输出。CPU 上的 global pose 正确后,仍需要确认 joint index、weight、matrix palette 顺序、buffer offset、实例索引和 shader 读取格式。上一章已经覆盖 GPU skinning 数据路径,本章只强调它在质量复盘中的位置:如果 raw、decoded、retarget 后的 CPU pose 都正确,而屏幕上肢体断裂或局部爆开,问题应转到 skinning buffer 和 shader 输入。首要排查对象此时应转到 skinning buffer 和 shader 输入。
下表给出常见运行时症状与首要检查点。它适合用作调试面板或 QA 记录模板。
| 视觉症状 | 首要检查点 | 高概率原因 | 需要记录的证据 |
|---|---|---|---|
| 脚底滑动 | root motion 与 foot contact window | translation 压缩误差、sync marker 偏移、retarget 比例错误 | root 曲线、foot global position、接触帧 |
| 手部偏离道具 | hand end effector 与 weapon socket | chain mapping、retarget pose、IK 权重 | 源/目标手腕位置、socket transform、IK goal |
| 肩膀或髋部姿态异常 | retarget pose 与局部轴 | A-pose/T-pose 差异、骨骼轴不一致 | source/target reference pose、chain debug view |
| 远处角色跳帧 | LOD 更新频率与插值 | animation budget 降频、pose 复用错误 | LOD 等级、tick interval、插值开关 |
| 状态切换时卡顿 | stream cache 与 decode job | chunk 未预取、随机访问成本高 | cache miss、chunk ID、decode 时间 |
| 网格局部爆开 | matrix palette 与 joint buffer | GPU skinning 绑定或索引错误 | joint index、weight、palette offset、shader 输入 |
最终质量结论要同时回答四个问题:压缩是否在误差阈值内,retarget 是否保持动作语义,streaming 是否满足切换和预算,GPU skinning 是否消费了正确 pose。只要这四层分开记录,动画问题就能从“看起来怪”变成可定位的 track、bone、chunk、state 或 buffer 问题。
最小自检任务
给定一段 2 秒跑步动画:源骨架 75 个关节,目标骨架 82 个关节,目标角色比源角色高 15%,手臂更长。压缩后文件尺寸减少 65%。运行时现象是:源骨架上播放基本正常,target 角色脚底在落地时轻微滑动,右手在持枪动作中偏离武器 grip,远处 NPC 偶尔在状态切换第一帧卡顿。请写出你的排查顺序,并说明每一步要观察的数据或视觉证据。
答案要点
先在源骨架上做 raw clip 与 decoded clip 对比,记录 root translation、foot global position、hand global position 和最大误差时间点。源骨架播放基本正常说明压缩可能在整体阈值内,但仍要检查脚步窗口和右手相关骨骼是否存在局部峰值误差。
接着检查 retarget pose、chain mapping、pelvis 和比例策略。目标角色更高、手臂更长,脚底滑动要看 root motion 是否按目标腿长或角色高度调整,右手偏离 grip 要看 arm chain、twist bone、hand IK goal 和 weapon socket 是否在同一语义空间中验证。
然后检查状态机采样与 sync marker。跑步脚步滑动如果只在 blend 或 transition 中出现,应比较 transition duration、左右脚落地 marker、root velocity 和 blend tree speed 参数。
最后检查 streaming 和预算。远处 NPC 状态切换第一帧卡顿,应记录下一段 clip 的 chunk 是否预取、stream cache 是否命中、decode job 是否集中在切换帧,以及 LOD 降频更新是否使用插值。CPU pose 正确但屏幕变形异常时,再转到 matrix palette、joint index 和 GPU skinning buffer。
本章知识点总结
- 轨道输入:动画压缩处理的是 translation、rotation、scale、curve、morph weight 和 event 等轨道化时间序列。
- 压缩目标:压缩目标应拆成文件尺寸、常驻内存、解码带宽、随机访问能力和视觉误差阈值。
- 轨道分级:rotation、root translation、scale、contact curve 和 gameplay curve 需要按用途分配不同误差预算。
- 量化边界:translation 量化依赖值域,rotation 量化需要处理 quaternion 归一化、半球一致性和层级误差传播。
- 曲线拟合:曲线拟合与关键帧删减通过减少冗余 key 降低数据量,同时需要验证插值段中间的峰值误差。
- 误差空间:动画压缩验收应从 local error 提升到 global joint position error、skinned vertex error 和 contact error。
- Retarget 基准:retarget pose 决定源骨架和目标骨架的共同语义基准,基础姿态偏差会传播到所有动作。
- 链映射:chain mapping 比单个 bone 名称更适合处理骨骼数量、命名和比例不同的角色迁移。
- IK 修正:IK 约束适合修正手脚接触、持物和视线目标,同时需要观察中段姿态和运行时成本。
- Streaming 粒度:clip header、metadata、root motion summary、event 和 track chunk 应按加载优先级组织。
- 内存预算:动画运行时预算包含压缩缓存、解码临时数据、pose buffer 和 GPU skinning 资源。
- 质量分层:运行时质量复盘应依次检查压缩、retarget、采样与状态机、streaming 预算和 GPU skinning 输出。