09 着色(插值、高级纹理映射)
重心坐标
基础定义
几何定义
几何观点——利用面积比求重心坐标
由这个定义,可以求出重心的坐标。
重心坐标公式
可以通过几何定义和行列式求出重心坐标的公式:
插值
插值的作用:知道三角形顶点属性,三角形内部进行平滑过渡。
插值的属性:纹理坐标,颜色,法向量等等…
插值的方法:利用重心坐标进行插值。
透视矫正插值
我们的重心坐标往往都是在屏幕空间下所得到的,如果直接使用屏幕空间下的重心坐标进行插值会造成一定的误差,与在view space下是不一样的。
具体解决方案:
https://zhuanlan.zhihu.com/p/144331875
这一点在作业3中有所体现。
纹理过大过小的问题及解决方案
纹理过小
纹理过小会导致失真,因为屏幕空间几个pixel对应在纹理贴图UV坐标上都是一个texture,往往会导致严重的走样。
我们知道,可以将屏幕或者画布上的一个单元称之为像素 pixel,为了与纹理上的一个单元进行区别,特将后者称之为 纹理像素texel。
如图,红点是屏幕空间下一pixel对应的texel,一种想法是去取离它最近的点,这种想法是不可取的,会出现走样现象。
双线性插值
一种缓解因纹理过小带来的走样现象的方法是双线性插值。如图:
- 取texel最近的四个点
- 做上下双线性插值(水平两次,左右一次)或左右双线性插值
双向三次插值
相邻的16个点做水平和竖直的差值,利用三次方程进行两次插值,效果更好,但是计算速度很低。
方法对比
三幅图分别对应取最近、双线性插值、双向三次插值的效果对比。
纹理过大
纹理过大时,一个pixel对应多个texel,导致采样频率不足,最终出现摩尔纹和锯齿的走样现象。
远处地平面的一个像素,对应一个大块的纹理,简单的点采样不行。
知乎上看到的解释:
footprint:称一个pixel覆盖不同数量的texel的现象为footprint。
如上图所示一个屏幕空间的蓝色像素点离相机越远,对应在texture空间的范围也就越大,覆盖越来越多的texel。其实也就是越来越欠采样。
例:
近处圆圈中的footprint就比远处圆圈中的footprint小。
超采样Supersampling
类比抗锯齿的想法,一个pixel覆盖多个texel,那么便把一个像素分为更小的sample,sample覆盖的texel会更少,从而解决这个问题。
然而这样计算的代价很大。
Mipmap
计算使用Level等级D:利用屏幕像素的相邻像素点估算footprint大小再确定level等级。
重点是三线性插值。
三线性插值即对DLevel进行一次双线性插值,再对D+1Level进行一次双线性插值,然后对这两个结果进行一次线性插值,最终结果为双线性插值。
开销:两次查询一次插值。
然而Mipmap也有局限性,正如前文提到Mipmap只能预处理出正方形区域的均值,这导致远处过度模糊。
各向异性滤波Mipmap
真实情况屏幕空间上的区域对应在纹理区域上即footprint并不一定是正方形。
解决方法:各向异性过滤
- 允许对长条的区域进行范围查询,但是不能用于斜着的区域
- 生成各向异性过滤的图(Ripmaps)的开销是原本的三倍
- 各向异性的意思是,在不同的方向上它的表现各不相同
- 各向异性的几X是压缩几倍,也就是从左上角往右下角多几层
得到的结果比Mipmap更好。
EWA过滤
把任意不规则的形状拆成很多不同的圆形,去覆盖这个形状,多次查询自然可以覆盖,但是耗时大。