重心坐标
已知三角形顶点的属性,如何在三角形内部进行任何属性的插值?

-
在三角形ABC所在的平面中任意一点(x,y),都可以用三角形三个顶点的线性组合来表示
-
ABC顶点前面的系数α + β + γ = 1,(α , β , γ)就是用来描述此三角形的重心坐标
-
如果点在三角形内α β γ都必须 ≥ 0
(α + β + γ = 1,是为了限制要求的点在平面内)

根据上述定理可得
A点的重心坐标就是(1,0,0)
如何求出α, β, γ?

设三角形内一点,点P,连接PA,PB,PC,会形成三个小三角形Aa,Ab,Ac,P的重心坐标就是小三角形面积占大三角形面积的比
α = Aa/(Aa + Ab + Ac)
所以可以求一个特殊的点,三角形重心,三角形重心将三角形划分为三个等面积的小三角形。
所以三角形重心的重心坐标为

对于三维空间中的点,不能保证其被投影后的重心坐标不变
如果想插值三维空间中的属性,就应该插值三维空间中的坐标。
因为在做光栅化时,需要知道像素中心在三角形的什么位置,此时不能直接求重心坐标进行插值
需要将该点重新投影回三维空间中,在三维空间中计算重心坐标插值
应用纹理

屏幕上的采样点(x,y)可以用重心坐标算出在纹理中采样的uv,得到对应纹理
纹理放大
当低分辨率纹理应用到高分辨率的屏幕上,纹理就会被拉大。
可以这样理解,我有一张图片(纹理),要放到分辨率比图片高的屏幕上,那么可以想象,反过来的过程,我把大量的像素映射到图片里,那相邻的像素就挨着很近,那么属性(颜色)就基本一样了,就会产生锯齿.
对于任意一点,可以找到对应纹理上的位置,位置可能不是整数,将位置坐标四舍五入,然后取纹理上的值
这样的话,一个texel就可能会被映射到多个pixel上,也就说可能在3*3的像素内用了同一个纹理的元素(texel)
这样就会产生马赛克效果如图Nearest
双线性插值

先用插值出来
再用插值出来
再把和进行插值,得到红点的最终值,即为双线性插值
得到图Bilinear
图Bicubic是将周围16个进行立方插值
纹理缩小
很大的纹理应用在一个像素中. 可以这样理解,我有一张图片(纹理),要放到分辨率比图片小的像素区域上,那么可以想象反过来的过程,少量的像素映射到图片上,那一个像素所在纹理上所占的区域就很大了.那相邻的像素的属性就差别很大了(因为在图片里离得很远),就会出现问题.
如果直接简单的使用线性插值进行采样会得到右图,远处有摩尔纹近处有锯齿
远处的一个像素就会覆盖很大一片的纹理区域,单纯以像素的中心是标准取纹理的值是不对的
这其实就是转变为了采样率不足的问题,之前解决采样率不足的问题我们可以使用SSAA,每个像素内分为若干小像素进行采样
以512个小像素为例,得到的结果如下图

正确,但花费了512倍的性能
既然采样有问题,那我们如果可以直接查询而不采样呢?
Mipmap
理缩小时,一个屏幕上的像素对应了纹理上的多个纹素,使图像看起来就变得模糊。
所以引出了Mipmap(多级渐远纹理) 技术
将原纹理提前用滤波处理得到很多更小的图像,当物体远离相机时,直接查询较小的纹理,得到正确的结果像素
Mipmap就可以实现我们需要的查询,但仅仅是近似的、正方形的查询

因为生成了多个较小的图像,需要额外储存生成的小图像
- 所以Mipmap占用的额外空间是原来的1/3
这是一种典型的空间换时间的思想

要查询在屏幕空间内的某像素,映射在纹理空间内占多大区域
可以将自己中心和邻居的中心分别投影到纹理空间内,这样就能知道在纹理空间中,该点和邻居点之间的距离L,要求的区域可以近似为以L为边长的正方形区域

但是会出现不连续的纹理映射,因为查的纹理都是整数层,比如我们无法直接查询1.5层的Mipmap

所以需要在两层之间进行插值,称为三线性插值


各向异性过滤
运用上述Mipmap后,在远处产生的图像很模糊,因为Mipmap是近似的、正方形的查询
只能查询正方形区域,而且三线性插值也是近似

屏幕上的像素映射到纹理上不一定是正方形,对于不是正方形的Mipmap就无法处理。
如下图,对于右边不是正方形但是是比较规则的矩形,我们可以用其他方法提供查询

将原图宽度不变长度压缩,长度不变宽度压缩就可以提供矩形的查找,即为各向异性过滤
经常看到的各向异性过滤x2x4等,指的是要生成多少层的压缩图,x2就是一层,x4就是两层。占用的空间逐渐向三倍靠拢

但各向异性过滤也只是能解决映射在纹理空间是比较规则的矩形的情况,当出现不规则矩形的时候也无法处理

所以又引出了EWA过滤,EWA过滤可以将任意形状拆分为很多大小不同的椭圆,经过多次查询,就能查询出最终的结果。
但是代价也是需要多次查询的时间

