一种简单、快速、高效的多边形减面算法

 

一种简单、快速、高效的多边形减面算法
A Simple, Fast, and Effective Polygon Reduction Algorithm

Stan Melax 正在加拿大亚伯达大学攻读计算机科学博士学位,致力于研究交互式3D技术和算法。他同时是Bioware的技术总监,曾经参与《超钢战神》这款游戏的制作,现在正在为他们的下一款游戏实现非常酷的3D效果,你可以通过电子邮件跟他联络:melax@cs.ualberta.ca

 

 

  如果你是一个游戏开发者,那么3D 多边形模型已经成为你日常生活中的一部分,并且你一定对一些3D概念例如每秒多边形数量、低面模型以及细节层次等等非常熟悉了。你可能也同样知道多边形减面算法的目的在于通过一个有着大量多边形的高细节的模型生成一个多边形数量比它少、但是看起来却跟原模型很相像的低面模型。这篇文章解释了一种实现自动减面的方法,并且附带的讨论了多边形减面的有用之处。在我们开始之前,我建议你去下载我的一个程序:BUNNYLOD.EXE,它展示了我将要阐述的这项技术。你可以在Game Develop网站上找到它。

  • 问题的由来

  在深入这个很“牛X”的3D算法之前,你可能会问你自己真的有必要关注它吗?要知道,已经有一些商业的插件和工具来为你减少多边形数量了。
  然而,下面的几条理由会告诉你为什么需要实现自己的减面算法:

  • 你使用的多边形减面工具生成的结果无法满足你的特殊需求,因此你希望做一个自己的工具。
  • 你当前使用的多边形减面工具可能无法产生减面过程中的变化信息,而你却希望利用这些变化信息来使不同的细节层次之间的转换更加平滑。
  • 你希望将生产过程自动化,这样的话美术人员就仅仅需要创建一个细节适当的模型,然后游戏引擎就能自动创建模型其余的细节层次。
  • 你正在制作一个VRML浏览器,你希望提供一个菜单项来简化那些巨大的VRML文件。那些把这些巨大的文件放到网上的超级计算机用户没有想到这些文件在普通家用电脑上显示帧速率会比较低。
  • 你在你的游戏中使用的特效改变了物体的几何形状,增加了多边形的数量,你需要一个方法来使你的引擎能够实时地快速减少多边形数量。

  你对此怀疑?图1展示了一个具体的实例,一个游戏引擎对减少多边形这种特性的需求。


图1 爆炸效果对多边形数量的影响

  在Bioware,我实现了实时的爆炸效果,并且把它们应用在了我们开发的一个游戏原型上,以便给我们的出版商留下深刻印象。玩家可以射击和爆破他们瞄准的实心物体表面的任意块。通过子弹撞击而改变游戏环境比典型的“定点爆破”这种只能在游戏世界中改变预先设定项的技术更棒。遗憾的是,重复不断的使用爆破效果会在物体上产生大量附加的三角形,如同你在图1中看到的一样。许多添加的面是很小的或者是碎片,不会对游戏的视觉效果产生丝毫的影响——它们仅仅是让游戏更慢。这种情况下就要求有实时的多边形减面功能,所以我开始寻找一种能够高效地完成这项工作的算法。

  • 坍塌边

  在我着手处理这个问题之前,我跟亚伯达大学图形实验室的一些人学习了多边形减面。(它让我跟一个团队一起工作,从而弄明白这个非常难的算法是如何工作的,并且弄明白什么样的技术适用于什么样的任务。)最近这个领域出现了很多研究成果,但其中大多数比较好的技术都是 H.Hpppe 的渐进网格算法的改进和变形(参见“更多的信息”)。那些技术都是通过重复不断的使用一个简单的边坍塌操作来降低模型的复杂度,见图2。


图2 边塌陷

  在这个操作里面,u和v两个顶点(边uv)被选中并且其中一个顶点(这里是u)“移动”或者说“坍塌”到另一个顶点(这个例子里是v)。下面这些步骤说明如何实现这个操作:
1. 去除所有既包含顶点u又包含顶点v的三角形(换一种说法,去除所有以uv为边的三角形)。
2. 更新所有剩下的三角形,把所有用到顶点u的地方都用顶点v代替。
3. 移除顶点u。
重复以上的过程,直到多边形的数量达到了预期数量。每一次重复的过程中,通常会移除一个顶点、两个面、三条边。图3展示了一个简单的例子。


图3 多边形经过一系列边坍塌之后减少了面数

  • 选择下一条边进行坍塌

  要产生效果比较好的底面模型的诀窍在于要正确地选择坍塌的边,能够在坍塌的时候最小程度的影响模型的视觉变化。研究者提出了各种各样的方法来使在每一次坍塌的时候能够选择出“最小影响”的边。但遗憾的是,最好的那种方法非常非常复杂(也就是说,很难实现),并且要花大量时间用于运算。因此这推动我要找到一种能够在游戏运行阶段减少多边形面数的方法,我做了很多实验,最后终于为这个选择边的过程开发了一种简单又超快的方法来生成相当不错的低面模型。

  显然,先要去除那些小细节。同时要注意的是,对于那些在同一平面上的表面,只需要很少的多边形就可以表示,同时高度弯曲的曲面则需要更多的多边形来表示。根据以上这些,我们定义了:一条边是否要坍塌,取决于它的边长与曲率值的乘积。为了找到在uv方向上距离别的三角形最远的u的临接三角形,我们通过比较两个面的法线的点积得到坍塌边uv的曲率值。方程式1展现了用更多正式符号表示的求边坍塌值的公式。详见源码(你可以在Game Developer网站上下载到源代码)。


Tu是包含顶点u的三角形的集合,Tuv是同时包含顶点u和顶点v的三角形的集合。
方程式1 求边坍塌值的方程式

  你可以看到,这个算法在决定哪一条边坍塌的时候对于面的曲率和大小做了平衡。要注意的是顶点u到v的坍塌值不一定和顶点v到u的坍塌值相同。此外,这个公式对于脊状的边的坍塌也是有效的。即使这条脊有可能是一个锐角,或者是直角,都没有关系。图4举例说明了这种情况。非常明显的,在平面区域中间的顶点B,可以被坍塌到顶点A或者顶点C。角上的顶点C应该最后被保留下来。如果把上面的顶点A坍塌到内部的顶点B,那就会非常糟糕。不过,顶点A可以沿着脊坍塌到顶点C,这丝毫不会影响这个模型的外观。


图4 好的和差的边坍塌

  如果你正在实作你自己的减面算法,你可能希望能够用这个公式做实验,来看看是否满足你的要求。例如,对于一个动画模型,你可能希望能够改进公式,使它能够在判断潜在的坍塌边的时候可以参考不止一个动画关键帧的数据。如果对于你来说,模型质量比减面算法所需要的执行时间更重要的话,你应该考虑使用Hoppe的函数。我们已经添加了很多扩展用来处理贴图坐标、顶点法线、邻接边,以及表面断裂(比如贴图接缝)。

  • 结果

  先显示一个原来的模型,然后显示简化后的模型,这是对多边形减面算法效果的最好证明。大多数的研究论文都用非常高面高细节的模型减面来证明它们的效果,原始模型接近100,000个多边形,简化后的模型只有10,000个多边形。对于3D游戏来说,更恰当(并且跟有挑战性)的测试是生成一个只有几百个多边形的模型,以此展示算法的强大威力。


图5 453个、200个以及100个顶点的小兔子模型(从左到右)


图6 随机选择坍塌边(200个顶点)

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值