← ALL ARTICLES
动画系统5 MIN READ

角色布料

全库目录221
本文目录8

渲染衣服有很多顶点,全部用于实时求解成本过高。角色布料让低模代理负责约束与碰撞,再把运动传到高模。代理映射、身体碰撞和瞬移重置是一条完整集成链,PBD公式由物理专篇解释。

模拟代理映射

渲染顶点可以绑定到低模模拟三角形的重心坐标,再保留离面偏移。以下 HLSL 片段输入同一世界空间的三个模拟顶点、权重和长度单位的偏移,输出渲染位置。宿主先按边长尺度检查三角形退化与翻转,不合格时回退到蒙皮位置;函数只接收通过检查的三角形,且叉积的长度平方为有限正数。

hlsl
float3 BindRenderVertex(float3 first, float3 second, float3 third,
                        float3 weights, float offset)
{
    float3 surface = first * weights.x
                   + second * weights.y
                   + third * weights.z;
    float3 areaNormal = cross(second - first, third - first);
    float inverseLength = rsqrt(dot(areaNormal, areaNormal));
    float3 normal = areaNormal * inverseLength;
    return surface + normal * offset;
}

退化三角形的回退在调用前完成,重心权重与绑定三角形来自离线映射。归一化采用实际面积长度,固定的面积平方下限会使单位或代理尺度改变时离面偏移缩水;例如两条垂直边各0.1毫米,面积法线长度平方为10⁻¹⁶平方米的平方,钳到10⁻¹²会把法线长度压成0.01。该例只说明位置传递,完整表示还需法线、蒙皮变换、碰撞厚度和 LOD 切换映射。将同一运动输入传给多个渲染密度,检查形态一致性。

重心绑定的权重和应为一。例如三角形顶点为 (0,0,0)(0,0,0)、(1,0,0)(1,0,0)、(0,1,0)(0,1,0),权重 (0.2,0.3,0.5)(0.2,0.3,0.5) 先给出表面位置 (0.3,0.5,0)(0.3,0.5,0),偏移 0.01 米再把顶点放到法线方向一厘米处。代理整片平移时,映射位置应平移同样距离。代理翻面会使法线翻转,薄衣服的厚度偏移随之换边,因此绑定阶段需要一致绕序,运行时监测退化与翻转,并回退到蒙皮位置。

布料模拟与稳定性

布料的表示层级

布料可以按成本分为:

  1. 烘焙在动画片段中的辅助骨骼;
  2. Spring/Dynamic 骨骼;
  3. 低模模拟网格的实时布料;
  4. 高质量离线模拟或缓存播放。

渲染网格通常太密,不能直接作为模拟网格。模拟网格用更少粒子求解,再通过 Skin/Wrap 映射驱动渲染网格。

碰撞与穿插

物理代理先预测位置,再求距离、弯曲和碰撞约束,最后映射到渲染网格。Compliance与乘子更新由 XPBD 解释;本页关注代理密度、角色碰撞与重置。

角色碰撞常用 Capsule/Sphere 近似身体。碰撞体过小会露皮肤,过大则让衣服悬空。

Self 碰撞成本高,尤其多层衣物。常见工程手段包括:

  • 降低模拟网格密度;
  • 增加 Substep 并限制最大速度;
  • 使用层级、厚度和碰撞组;
  • 对身体使用 SDF;
  • 在不重要区域关闭自碰撞;
  • 用 Animation/Corrective Shape 掩盖极端姿势。

Teleport、低帧率和角色瞬移必须重置或重新初始化模拟,否则历史速度会把布料甩飞。

角色与服装穿模

穿模是服装与身体在动画过程中互相穿透的现象。它在两种情况下高发:服装没有独立骨骼动画、仅由身体骨骼驱动时;以及换装系统允许任意组合、无法为每对组合单独调整时。

治理手段按介入时机分为三类,通常需要组合使用。

离线裁剪

思路很直接:被衣服完全遮住的身体部分永远看不见,删掉即可。删掉之后自然不会穿出来。

一种候选判定是从服装顶点沿法线反方向投射射线,按距离标记身体三角形。它只反映当前姿态,不能证明某块身体在所有动作和换装状态下都被遮住。正式裁剪集合应经过动作覆盖与开口检查;领口、袖口和可拆衣物使用明确的保留区域。生成的新网格缓存到本地,运行时直接使用。

遍历量很大,应当用作业系统或计算着色器加速。有两个实现细节容易出错:碰撞体需在查询前完成创建,并按所用物理接口同步其变换,否则可能查询到缺失或过期状态;多层服装要按层级顺序处理,并防止服装触发自身或同链上其他网格的裁剪。

离线裁剪可避免运行时再次做遮挡裁剪,生成的网格仍有正常加载、蒙皮和绘制成本。服装与体型组合越多,预生成产物和维护成本越高,需要限定组合或采用受控的运行时方案。

建模与权重约束

资产制作阶段可以先减少穿透来源:服装与身体之间保留足够间隙,服装的蒙皮权重尽量与对应身体部位一致。身体与服装的权重差异会改变相对形变,可能增加穿透风险,但相同权重也不能保证极端动作不穿模。需要同时检查网格间隙、骨骼变换、矫正形状与碰撞。

关节弯曲极限处是重灾区,肘部、膝盖、肩部需要单独检查。

运行时约束

物理模拟的布料需要正确配置碰撞体。身体碰撞体过于粗糙会让布料贴不紧,过于精细则模拟成本上升。

布料顶点数过多时,部分布料系统会拒绝工作或性能急剧下降。常见做法是用低模布料网格做模拟,再把结果传递到高模——这与毛发的引导线到发丝是同一思路。

验证

穿模必须用动画覆盖测试,静态姿势检查不出问题。做法是让角色遍历全部动画片段,在关键帧采样并自动检测穿透;换装系统则需要覆盖组合矩阵,至少覆盖每种服装与每种体型的配对。

验证方法

用极限姿态、低帧率、瞬移和体型组合检查穿透。显示模拟代理、绑定三角形、碰撞厚度和映射权重;退化代理要回退,裁剪身体只能基于覆盖验证。

实现状态:正文片段用于解释本页数据流与边界条件;完整宿主的编译、运行及性能测量尚未执行。可运行的独立模型以本页列出的具体测试为准。

正文抽取检查以等价C++17 CPU算术验证小三角形的0.01米离面偏移;这不包含GPU执行。绑定数据生成和退化回退由接入工程实现。

2026-10-22 执行 编译检查,DXC 将BindRenderVertex 的重心位置映射编译为 ps_6_0,结果通过。该结果只验证带最小输入声明的 HLSL 片段,完整材质、资产绑定、引擎运行与 GPU 性能仍未验证。

相关主题

参考资料

  • Macklin 等:XPBD:第1页摘要与引言:时间步长、迭代数和约束刚度;模拟到渲染网格的重心映射为本文实现方案。