Skip to content

让生成的角色拥有可以摆动的头发 ​

作者:Oleg Sidorkin,Cinevva CTO 兼联合创始人

生成的角色可以拥有看起来很逼真的发型,却仍然没有能够独立摆动的头发。输出结果可能是一个曲面、一组薄片,或彼此断开的部件。这些表示方式都无法告诉模拟器一根发丝从哪里开始、朝哪个方向生长,或者应当如何弯曲。

我们之前的头发实验从由美术人员完成绑定的虚拟形象和一款选定的马尾辫开始。这一次,我们从可复用的头发网格和青蛙角色入手。问题更加基础:我们能否适配一种发型,在其中追踪出有用的引导曲线,并让它们的根部在动画过程中保持附着?

在 46 种发型中,当前原型共提取出 10,467 条候选引导线,并为其中 10,346 条找到了头皮连接点,占 98.84%。这是附着结果,并不意味着自然头发运动的成功率达到了 98.84%。

试用网格及其引导线 ​

演示会立即加载。选择一种发型,然后使用头发检查在原始网格、网格加引导线,以及仅显示引导线三种模式之间切换。拖动预览画面可环绕观察;除了正面,也请检查背面。选择一项动画,查看附着点是否会随移动中的角色一起运动。

青色曲线已连接到头皮。橙色曲线则被拒绝。“显示建议根部”会显示建议的附着点。Long01 是一个很适合观察的高密度示例;法式辫子的不同变体则展现了连接分离片段时面临的挑战。你可以下载引导曲线,检查其中的点和附着元数据。

Open this demo in a full window ↗

符合条件的披散发型现在会使用一个实验性适配器,连接到上一篇文章中的共享头发求解器。它最多选择 24 条引导链,创建关节,并为可见网格和引导线叠加层赋予相同的蒙皮权重。发帽保持固定;不受支持的区域仍然绑定在头部。没有合格披散引导线的短发造型会继续使用刚性附着。两个法式辫子示例则保留各自独立的实验性关节链处理方式。切换检查视图时,动画播放状态会得到保留。

先适配,再建立附着 ​

我们从 MakeHuman 合集、脏辫变体和 Quaternius 资产中整理了 46 种 CC0 发型选项。演示中的每个选项都带有来源链接;资产目录和许可证清单保留了来源信息。这些是可复用的网格资产,而不是一套采用统一绑定方式的发丝库。

第一次放置的失败非常明显:头发落在了青蛙头部后方。基于包围盒的缩放虽然对齐了对象,却没有识别预期的头皮位置。现在,我们的适配流程会估算源发型的头顶位置,将它对齐到目标头部表面,并依据近似的头部包络,把与头部重叠的上方头发向外移动。

这与我们在服装文章中采用的拆分方式类似:放置资产、适配其形状、将其附着到骨架,以及赋予它次级运动,是几项不同的工作。发根应当留在头皮上,而头发的长度部分应当保持原有发型,不能塌落到身体表面。

我们特意选择了难以处理的青蛙:它头部宽大、眼睛凸起,而且比例并非人类比例。目前的上方/后方头皮遮罩是专门针对这个角色推断出来的。它并不是面向任意生成模型的自动头皮检测器。有些发型仍会遮住面部,或具有不合适的比例。

沿现有表面追踪路径 ​

我们会根据每个头发网格构建连通图。在这项分析中,由 UV 接缝分开的重合顶点会被焊接;用于渲染的源网格则保持不变。在每个连通分量内,我们会从一个初始根部候选点出发,寻找通向彼此分离端点的表面路径,然后将这些路径平滑处理并重新采样为曲线。

对于相邻顶点 i 和 j,图中边的代价就是它们之间的几何距离:

wij=‖xj−xi‖,P∗=arg⁡minP∑(i,j)∈Pwij.

这种最短路径构造会沿着网格表面前进。它不会发现符合生物规律的生长方向。最初选取的高位根部只是一项建议;之后可以根据与头皮的距离反转曲线方向。扁平发片通常能够提供有用的路径,而封闭发帽或断开的卷发则要模糊得多。

这些是候选引导曲线,并不是还原出的单根头发。一张发片可以代表许多可见发丝,而一条表面路径也可能横穿预期的头发流向。密集的青色覆盖看起来可能令人印象深刻,却会掩盖错误的方向。目视检查仍然是测试的一部分。

让发根跟随实际头皮 ​

引导线的一个端点会与符合条件的头皮三角形匹配。如果距离太远,我们会拒绝这个连接,而不是将它随意拉伸到头部。通过验证的发根会存储该三角形的顶点索引和重心权重。

对于动画身体上的三角形顶点 a(t)、b(t) 和 c(t),附着后的发根为:

r(t)=λaa(t)+λbb(t)+λcc(t),λa+λb+λc=1,λi≥0.

权重保持固定,而三角形顶点会随蒙皮移动。此前,如果仅将整个显示对象挂在头部节点下,在我们采样的 Walk 检查中,发根漂移最多可达 0.657 毫米。改为跟随已存储的三角形附着信息后,该误差降至数值精度范围:在四个动画时间点对 74 个 Long01 发根进行采样时,误差小于 10−12 米。

这是在场景采用米制约定下进行的数值一致性检查。它不能证明发际线在视觉上正确、曲线全程与表面保持适当间距,也不能证明它在所有动画中都保持稳定。

连接片段,同时保留不确定性 ​

有些发型由许多彼此断开的部件组成。远离头皮的片段可能是某束已附着头发的延续部分。我们会测试两个方向,并且只在端点足够接近且方向一致时,才将它连接到一条已通过验证的引导线上。

当前的连接规则采用 25 毫米的距离上限,且切线点积必须高于 0.5,这些数值均基于本场景的尺度。只有已经附着的路径才能成为父级,从而避免产生环。曲线长度、点数和连接轮次都有上限。这些阈值只是原型阶段的选择,并不是通用的头发参数。

连接操作为已通过验证的集合增加了 1,851 个连接。法式辫子变体从 136 条直接附着的引导线增加到全部 509 条均已连接;凌乱辫子则达到了 519 条中的 512 条。其余七个片段仍保持橙色。连接结果仍需审核:几何体彼此接近,并不能证明两个部件属于同一束头发。

探索测得的覆盖情况 ​

搜索某种发型,或仅显示存在被拒绝引导线的发型。链接会打开对应的实时检查视图。这些数字来自已保存的 46 种发型审计结果,并不是持续计算的物理效果评分。

46 of 46 styles · saved audit

下载完整的附着结果。

审计中的全部 46 种发型均成功加载,浏览器未出现错误。提取过程遗漏了三个 Elvs 网格中的 90 个顶点。四项专项测试会检查连通性、遗漏报告、可重建的头皮附着、片段连接,以及对远端片段的拒绝处理。我们检查了桌面视图和 390 像素宽的移动端视图;移动端页面没有出现水平溢出。

这些结果衡量的是这个发型库适配到这只青蛙上的表现。它们并未覆盖任意生成的几何体、所有姿势、自碰撞,或导出到其他引擎的情况。

距离真正的头发物理效果还需要完成什么? ​

当前的引导线提供了发根和候选路径。首个适配器现在会复用我们现有的固定时间步长弹簧、静止形状和接触求解器。在 Long01 上,它将 39,804 个网格顶点中的 18,204 个绑定到 24 条链;在受控测试中,一个采样的披散头发点相对于头部移动了 13.6 毫米。这验证了次级变形,但并未证明运动自然或动画没有碰撞。网格和叠加层使用相同的蒙皮场。我们仍需确保方向可靠、每束头发内的权重连贯,并开展广泛的运动检查。

接下来的关卡是审核有歧义的发根和片段连接,改进引导线选择和权重,同时避免跨越不同发束产生撕裂,并验证运动过程中的身体接触。自接触仍需要额外工作。导出后重新加载也必须保留这些绑定。

对于生成的角色,替换独立的头发表面是一种实用的起点。如果头部和头发融合在同一个网格中,则还需要满足另一个前提:识别头发区域,并在其下方建立可用的头皮。我们的青蛙实验没有解决这个分割问题。

现在,我们获得了一个可检查的中间结果:适配后的网格、明确的候选路径、会随表面移动的附着点,以及清晰可见的拒绝结果。下一步改进必须让这些路径的表现令人信服,而不能只是增加青色曲线的数量。