一、算法介绍
关于边塌陷的网格简化方法,SIGGRAPH 有一篇97年的论文Surface Simplification Using Quadric Error Metrics(Michael&&PaulS)对这个问题进行了深入的探讨。作业里的代码就是基于这篇论文来实现的。最为核心的思想就是通过对网格图形上的每一条边通过计算一个cost来维护一个堆,每次迭代都将这个堆中cost最小的边将它移除,然后重新计算各条现有边的损失值来维护堆,直到达到给定的简化率为止。
首先我们来关注第一个问题:为什么我们需要网格简化?相信平时玩大型3D游戏的时候大家都会看到在越来越精美的模型中也会掺杂着一些十分粗略的模型(比如篮球游戏中的观众),其目的也很好理解,模型的复杂性直接关系到它的计算成本,过于多的计算资源都被拿来对场景中的重要的不重要的模型生成来使用,势必会影响其流畅性。因此高精度的模型在几何运算时并不是必须的,取而代之的是一个相对简化的三维模型,那么如何自动计算生成这些三维简化模型就是网格精简算法所关注的目标。
论文中最核心和部分无疑就是计算这个cost的思想,我们分两块来说明论文这部分思想:首先,每一次迭代怎么计算这个Approximating Error With Quadrics。然后我们讨论怎么初始化这个ErrorQuadrics。
这一部分就是paper中具体说明这个cost计算的地方。该方法在选择一条合适的边进行迭代收缩时,定义了一个描述边收缩代价的变量Δ,具体如下:对于网格中的每个顶点v,我们预先定义一个4×4的对称误差矩阵Q,那么顶点v=[vxvyvz1]T的误差为其二次项形式Δ(v)=vTQv。假设对于一条收缩边(v1,v2),其收缩后顶点变为vbar,我们定义顶点vbar的误差矩阵Qbar为Qbar=Q1+Q2,对于如何计算顶点vbar的位置有两种策略:一种简单的策略就是在v1,v2和(v1+v2)/2中选择一个使得收缩代价Δ(vbar)最小的位置。另一种策略就是数值计算顶点vbar位置使得Δ(vbar)最小,由于Δ的表达式是一个二次项形式,因此令一阶导数为0,即,该式等价于求解:
其中qij为矩阵Qbar中对应的元素。如果系数矩阵可逆,那么通过求解上述方程就可以得到新顶点vbar的位置,如果系数矩阵不可逆,就通过第一种简单策略来得到新顶点vbar的位置。