1.重心坐标
为什么要进行插值?(因为有很多的计算实在三角形内部进行的,而我们需要形成一个平滑的过渡)
插值需要插值什么内容?(颜色,纹理映射,法线插值,可以对三角形的任意属性进行插值)
重心坐标定义在三角形上,三角形所在平面的点都可以由重心坐标表示,有三个数的线性组合来表示。如果点在三角形内,这三个系数都必须是非负,只有这样,才表达的是这个点一定在三角形内部
要得到任意一个点的重心坐标,可以通过面积比得到
重心是将三角形均分为三份
如果要计算任意一个点的重心坐标,有一个公式
在知道如何计算重心坐标后,那么就可以通过重心坐标来表示三角形中的任何一个点,这是一个三角形其余三个顶点组成的线性组合,那么同时也就说明三角形内任意一个点的属性也就可以通过这个线性组合来表示
有一点需要注意的是,重心坐标虽然运用简单,但有一个问题,在投影的变换下无法保证重心坐标不变、
2.纹理帖图
我们要怎么应用呢,屏幕上任意的采样点都有一个位置,据此计算出uv、在纹理上找到这个相应的值
但这样做会有各种各样的问题
问题1,如果纹理很小怎么办?
纹理本身太小,我们本身会在纹理上找到对应的值,这种纹理上的像素可以被称为 texel(纹理元素),可以使用简单的四舍五入,也就是说如果取到了小数将其整数化,会形成一个一个的格子,这样就会形成下图中左边这张图的效果
这种效果比较差,因为虽然纹理很小,但我们仍然希望得到一个连续的值,这样就又有了第二种方法,双线性插值,所谓的双线性插值,可以认为就是下图中我们需要解决的问题,我们该如何确定红点的值是多少
双线性插值的操作就是我们可以找到相邻的四个点,定义两个操作,第一个是线性插值,就是定义一个点x位于v0(0)和v1(1)之间,lerp就可以由这三个点表示,要实现双线性插值,就是先对水平或者数值方向上做一次插值,然后再根据插值得到的两个点,再做一次另外一个方向上的插值就可以了
最后得到的效果就是中间图片的效果,格子消失了,相比于双线性插值外,还有更好的方法,比如说图片中的第三种方法,取周围的16个点做三次插值
问题二 如果纹理太大呢?
这样引起的问题反而会更加严重,例如下面这个问题,如果取简单的操作,根据uv找纹理,就会产生走样
为什么会产生这样的现象,根据下面这张图就可以很好的解释,我们可以看到在近处的时候,每一个像素覆盖的很小,而随着越来越远,每一个像素都会覆盖很大一片的纹理,如果覆盖的范围越来越大,还认为中心的点采样作为整个面的值,那肯定是不行的
对于走样的问腿,我们之前的做法就是超采样,MSAA的方法,用更多的采样点
采样会引起走样,我们能不能使用一个方法避免采样,这是一个经典算法问题,范围查询,我们需要做到范围查询能查到任意大小的范围平均值,例如下面这张图,若是同一张图,近处的像素覆盖就很小,远处的覆盖范围就会很大
为了解决这个问题,图形学所使用的范围查询方法就是Mipmap,这个方法(快,近似,且只有正方形的范围查询),什么是mipmap,就是从一张图生成一系列的图,生成多层纹理,每高一层纹理,缩小一倍的分辨率
那么拿到图片后,我们需要先生成mipmap,相当于形成了一个图片金字塔,最后全部土拍你的存储量求出来是原来的4/3,我们需要得到近似的正方形,那么怎么得到每一个像素映射到纹理上时,所覆盖面积的大小呢,我们可以首先取像素自己本身的中心映射到uv上,然后取它邻居的像素中心映射到uv上,求出uv上两点之间的距离
此时再得到区域的大小后,根据这个像素的覆盖面积大小,可以去查在第几层这个给面积代表的就是一个像素,然后在mipmap中取出这个平均值就可以了,再做可视化
但是呢,如果仅仅只分这些层就会出现很明显的不连续的现象,比如1.8层,那么要得到1.8层的值,我们就可以取第一层,再取第二层,再两次双线性插值的基础上再做一次线性插值
这样就可以得到面积内的平均,这种插值的方法叫做三线性插值,本身的开销也不是很大
但是使用mipmap的缺点是,在远处会出现过分模糊的情况,如下图所示
怎么解决这个问题呢,可以使用一个方法叫做各向异性过滤,在每一行中,只变化宽度,而在每一列中,只会变化高度,比起mipmap中每一个都是方形,而现在就是有了一种矩形的选择
这在下面图中可以明显的看到为什么,有矩形的区域范围查询会更好,但这样其实也只是解决了部分问题
例如EWA方法,使用圆形去覆盖不规则的形状