一、网格细分
网格细分指的是将原有模型上的网格分成更多个网格,从而将模型变得更加精细,提高渲染出来的效果,让画面更加漂亮
下图就是一个网格细分的示意,左图是细分前的效果,右图是细分后的效果
首先说一下,Loop是人名,不是循环。Loop算法的主要过程如下:
如上图所示,白色顶点就是新顶点的其中一个,其位置由老顶点加权平均构成,因为AB距离新顶点较近,所以权重较大相比CD较大
特殊情况就是一个边仅仅属于一个三角形面(也就是说,该三角形面位于模型的边缘位置),那么在该条边上新加一个顶点的坐标可以表示为两个端点的平均
O表示老顶点原来的位置,O‘表示老顶点现在的位置,n表示的是老顶点的度(有多少个边连接到这个顶点上),β表示的是一个和n有关的权重,后面的累加表示周围顶点的坐标和
原先老顶点的权重是1-nβ,如果老顶点的度越大,表示周围的顶点越多,那么,在重新调整位置的时候,老顶点原来的权重也就不是那么重要,因此,经过1-nβ的计算后,老顶点的权重就会变小
反之,如果如果老顶点的度越小,表示周围的顶点越小,那么,在重新调整位置的时候,老顶点原来的权重就需要很大,1-nβ的计算后,老顶点的权重就会变大
Loop细分算法只适用于网格都是三角形的情况,如果出现了多边形网格,Loop算法就不适用了,所以,为了解决多边形网格的细分问题,Catmull-Clark网格细分算法出现了
在每个面的中心或者重心都新加一个点,在每个边的中点也新加一个点,将新顶点连接起来,效果如下图
1、新增2个奇点,有几个非四边形,就会多几个奇点,现在一共4个奇点
所以,这次细分完之后,只要在每个四边形上多加四个顶点和一个中心点,就可以进行无限细分
点的类型也被分为了三种,首先是面点,就是四个顶点取平均,如下如中的f
二、网格简化
网格简化和网格细分的作用相反,主要是为了降低渲染效果,加快渲染速度,为啥要这么做呢?比如游戏中有个骷髅头,如果无论远近全部采用一样的模型,那么,当模型离相机很远时,就会和很近时的定点数相同,渲染速率相同,但是,其实在远处,并不需要这么精确的模型,即使是300个三角的骷髅,在远处的效果和3W个三角形的模型也没差多少,因此就有了网格简化的需求
所谓边坍缩算法就是一个边的两个顶点合成为一个顶点,从而让一条边小时,而且合成后还要最大程度上保持原有模型的形状
为了最大程度上保持原有模型的形状,引入了二次误差度量,该度量方法的原则就是合并后的新顶点,应当到合并前两个老顶点周围若干三角形所在平面的距离的平方和最小
对于一个三角面,所在平面方程为ax + by + cz + d = 0。对于这种平面方程, 空间中任意一点到这个平面的距离就是直接点的xyz代入。
因此,距离的平方的函数为d = (ax + by + cz + d)^2。那么所有平面的距离平方和就是把所有三角面的这个函数相加,最后求最小值。
之后,对deltaV进行求偏导,是的三个方向的偏微分都为0,就能得出哪两个点合并之后,deltaV最小
如果矩阵不可逆,则对V1和V2进行插值查找最优点,如果仍不存在最优,直接认为合并后的点是(v1+v2)/2
上述过程只是对任意一对点的计算,而最终需要对所有对儿点都进行这个流程,
因为每次简化都能保存简化前的网格结构,所以,可以将这个网格结构全都保存起来,当切换相机的远近景时,可以显示不同的网格结构
参考
Loop 细分曲面(loop subdivision)详解,附Python完整代码_McQueen_LT的博客-CSDN博客
【图形学】网格简化及边坍缩( Edge Collapse )算法_wk_119的博客-CSDN博客
Surface Simplification Using Quadric Error Metrics (mgarland.org)
GAMES101-现代计算机图形学入门-闫令琪_哔哩哔哩_bilibili
欢迎大家评论交流,作者水平有限,如有错误,欢迎指出