游戏《孢子》的思考 —— Ear Clipping算法

这篇博客介绍了计算机图形学中的Ear Clipping算法,以及我对其的思考。


背景

偶尔翻出来几个以前的老游戏玩了一下,其中包括了孢子。说实话,以前作为玩家的时候感觉这个游戏也就一般。但是现在作为游戏开发者发现这个游戏涉及到一些很酷的技术,包括自定义的肢体(Skin方面)、动画的泛化(Animation Retargeting方面)以及IK结算的泛化。因此查找了一些这方面的资料,尝试了解一些这方面的知识。

搜索了一些资料之后,决定挨个的去补一补对应的知识点。有些知识点在大学也学过但是记忆已经模糊了,有些则是完全没听过的领域,统一记录下来吧,也当作是对以往的知识点的整理。

这篇博客介绍的就是孢子中使用的用于将自定义肢体模型进行细分化的Ear Clipping算法。

在孢子的开发者博客中提到,在项目开发期,Marching Cube算法仍然处于专利保护期(虽然游戏发行的时候专利已经过期了……),因此开发者决定使用Ear Clipping算法将整个网格进行细分处理。

算法介绍

Ear Clipping算法指的是用于将一个普通多边形拆解为一系列的三角形,这些三角形的顶点都来自原来的普通多边形,如下图:

游戏《孢子》的思考 —— Ear Clipping算法_第1张图片

各类定义

普通多边形的定义

上文提到了普通多边形(Simple polygon),普通多边形定义如下:

  1. 普通多边形由n个顶点( V0 Vn1 )组成。
  2. 连续的顶点通过一条边< Vi , Vi+1 >组成, 0in2 ,并且由边< Vn1 , V0 >链接首尾两个点。
  3. 每个顶点都有且只有两条边相连,没两条边都只允许相交于顶点。

如下图,最左边的是一个普通多边形,中间的不是普通多边形因为顶点 V1 连接了多于两条边,右边的不是普通多边形因为1和4的边相交于非顶点。

游戏《孢子》的思考 —— Ear Clipping算法_第2张图片

Ear Tip

针对于三个连续的顶点 Vi0,Vi1,Vi2 ,如果线段 Vi0Vi2 是多边形的一根对角线,那么顶点 Vi1 就是一个Ear tip.

说的更通俗一点,如果线段 Vi0Vi2 完全位于多边形内部,并且顶点 Vi1 是一个凸顶点,那么顶点 Vi1 就是一个Ear tip。

算法过程

算法过程其实相对来讲比较简单:

  1. 首先建立起对应顶点的双向链表 V
  2. 构建初始的凸顶点集 C 和凹顶点集 R ,并且构建出初始的Ear Tips集 E
  3. 每次从Ear Tips集中删除一个元素 Vi 并且在多边形顶点集中也删除之,并且在生成的三角形链表中添加入对应的三角形< Vi1,Vi,Vi+1 >。之后刷新临接的顶点,计算是否生成了新的凸顶点以及Ear Tip。
  4. 重复操作3,直到链表中只剩下三个顶点,此时就是最后的三角形了。

例如下图,在多边形中删除了Ear Tip 3,此时三角形< V2,V3,V4 >就被放入三角形列表中。

游戏《孢子》的思考 —— Ear Clipping算法_第3张图片

再如下图,在多边形中删除了Ear Tip 4,此时三角形< V2,V4,V5 >被加入三角形链表中,并且顶点5变成了新的Ear和凸顶点,此时需要更新对应的链表。

完整过程如下:

游戏《孢子》的思考 —— Ear Clipping算法_第4张图片

不难看出,Ear Clipping算法的时间复杂度是 O(n2) ,并且三角化的最终质量很大程度上取决于顶点顺序。在某些情况下很容易生成过于细长的三角形,这样不利于Skinning的进行。

思考

Ear Clipping算法常用于将Polygons进行三角化,但是在孢子中最后的躯干模型往往是基于一个隐式曲面(Implicit Surface),也就是说是连续的,此时需要将隐式曲面转化为多边形之后,再进行操作。

但是看得出来孢子中并没有使用这个算法进行最终的三角化。在最终的隐式曲面方程定型之后,他们使用的是Graphics Gems III的文章Compact Isocontours from Sampled Data,对应的tech report链接。据说是强烈推荐,下一篇文章就写这个吧……

<全文完>

你可能感兴趣的:(图形学)