我们制作一个角色生成器,身体、面部和一堆衣物碎片可以随意组合。我们需要更便宜的这些角色版本用于人群,因此背景中的人不再像前景中的人那样昂贵。

这就是我们最终得到的。

https://preview.redd.it/dk31nbgtx7yh1.png?width=2800&format=png&au&s=b7810cd15d47312feaf2a854f8243ac736176152

https://preview.redd.it/a8kqlbgtx7yh1.png?width=2800&format=png&au&s=c50649bad13c055aae1c17add917ac0f1c019026

尝试 1:对每个部件运行网格简化

我们首先把每个衣物网格交给 meshoptimizer,并要求它保留四分之一的三角形。

其中一位角色的结果如下(左侧为原始,中间为简化)。

https://preview.redd.it/gx91q8jyx7yh1.png?width=3024&format=png&au&s=97c6ab095ae1737320b2ddf695c2622ffe426986

那些深色的细条是衬衫的内层,青色的部分是下面的 T 恤。衣物由几毫米的表面之间隔开,例如衬衫的外层、内层以及下面的 T 恤。简化器试图保持每个表面接近其原始形状,但它不知道哪个附近的表面应该在上方。几毫米的曲面平整可能会把一个表面压到另一个表面上。

tempting 的是忽略这一点,因为背景中的人的衬衫根本不会被检查。但远处时,每个像素的颜色大约是落在该像素的所有内容的平均颜色。几个错误的表面三角形混入浅色衬衫会使平均颜色变暗,导致衬衫颜色在角色切换到更简单的层次时明显变化。

要求更少的三角形反而让情况更糟。

https://preview.redd.it/ppnfihmzx7yh1.png?width=2012&format=png&au&s=0843f4caee779453695446d687289156a32020ba

尝试 2:保护危险区域

因此我们找出每个位置,在那里另一层紧贴在下面,并告诉简化器不要修改那些顶点。这是第一次对比中的第三张图。它也几乎没有被简化,因为服装几乎所有部位都紧贴着另一层。

该版本成为我们最近的层级,并且仍在使用。更远的层级必须将三角形数量降低到四分之一及以下,保护顶点让更多的三角形保留下来。

尝试 3:让顶点移动,然后修复重叠

简化器也可以把顶点移动到最能保持原始形状的位置,这在低三角数时效果更好。每个部件单独来看都很好,但毛衣穿过上面的外套。

https://preview.redd.it/598gcmu0y7yh1.png?width=2012&format=png&au&s=dccec0d6ca9908c07e5a50441eb28c6a3b4da252

我们的第一个想法是,在简化后检查每个外套顶点,如果它落在毛衣内部则把它推回去。该检查只检查每个三角形的角点。

https://preview.redd.it/b8x0yrg2y7yh1.png?width=900&format=png&au&s=43bb8e74a5172a6b8ff4a34745d237b7d23ea7ad

我们还尝试在多个姿势和身体形状之间检查三角形内部的点,但一次性的修复在另一个姿势中会导致问题。

在相机看不见的地方作弊

没有人会从内部观察远处的 NPC,所以外套只需要在它应该在上方的像素处赢得深度测试。

每个简化部件的顶点都存储一个额外的数值,表示其下方的衣物层数。身体为 0,毛衣为 1,外套为 2。在着色器中,每个顶点向相机移动该数量的小步数。

每个顶点沿着它自己与相机之间的直线移动,保持其在屏幕上的位置,同时改变其深度。给外层顶点更大的偏移有助于它在简化表面重叠时赢得深度测试。

这里是毛衣和外套作为两个简单的管子(先简化,再使用技巧简化)。

https://preview.redd.it/3hm0qck4y7yh1.png?width=1800&format=png&au&s=d43c7fa95889229ecd2398813dcaa154eb5121db

下面是同一管子从不同角度的视图。右侧的白色轮廓是简化外套的实际位置。绘制的外套向原始相机方向缩小,毛衣因此露出来。

https://preview.redd.it/z3g9hif7y7yh1.png?width=2000&format=png&au&s=2d3026a3cf8026d31c0aa6074c4ccf06d66f47a3

从除该相机以外的任何位置看,作弊很明显。这没问题,因为着色器每帧都会根据当前相机重新计算偏移。

另外两点让它在真实衣物上表现得更好:

  • 有些服装包含内部表面,这些表面被其外层表面覆盖。对于远处的层级,我们删除被覆盖的区域,仅保留边缘附近可能可见的内部表面带。

  • 层数在网格上平滑,使得相邻顶点的偏移差异不大,防止表面撕裂。

随后主要进行了较小的 Unity 工作。例如,Update When Offscreen 仍然每帧为隐藏的 LOD 级别进行骨骼动画,每个远处层级被合并到单个渲染器中。在缩放测试中,角色在预期距离处保持一致,且过渡难以察觉。

小多少算小?

以下是每个层级在大约 1080p 设置下的绘制尺寸,放大后可供观察像素。

https://preview.redd.it/g588w6t8y7yh1.png?width=2810&format=png&au&s=d20daebc4b4b4ee8691c9997424dee61a2a68de5

(这是我们在 Asset Store 上的 Archetype 角色生成器。)