欢迎来到NiceSpace!祝大家开心每一天!
  • C++
  • 图形学
3D图形学总结(十二)—纹理滤波

    双线性纹理滤波

    之前进行的纹理映射过程中,包括仿射纹理映射和透视纹理映射,采用的都是点采样,即使用纹理坐标u和v,丢弃了它的小数部分(或者进行四舍五入)。

    这样做的问题就是本来可以用作绘制更高的图像信息被丢弃了,这就是双线性滤波的作用,不丢弃小数部分,而是根据纹理坐标u,v采集纹理图中相应点周围的元素,并通过线性的方式对他们进行平均。

    假设有一个64x64的纹理图,如下图所示我们总是需要采集周围的4个纹素然后以线性的方式计算平均值。

    uv为(0.5,0.5)时,pfinal = 0.5* 0.5 * p0 + 0.5* 0.5 * p1 + 0.5* 0.5 * p2 + 0.5* 0.5 * p3。

    uv为(0.25,0.25)时,pfinal = (1-0.25)*(1-0.25)*p0 + (0.25)*(1-0.25)*p1 + (1-0.25)*(0.25)*p2 + 0.25 * 0.25*p3

    由上可以看出,每个纹素采集的部分与占用的面积相关。

    下面可以看下使用双线性纹理滤波的效果图:

    使用前:

    上图是相机距离物体非常近时,一个128x128的物体纹理,映射到了一个800x600的屏幕上,图像被放大拉伸(只截取了部分屏幕),图中我们可以很明显的看出有很多小方框,这是因为之前的点采样,一个像素点被映射到屏幕上的好些个像素点上,所以会产生这种小方框的效果。

    下面是经过双线性纹理滤波后的效果图:

    上图我们可以发现已经没有小方框了,这就是双线性滤波后的效果,但是弊端是双线性插值的计算量要大一些。

Mipmapping

    在进行纹理映射时,可能出现的问题就是闪烁,当纹理图中的高频元素进入或者离开视野以及纹理图被缩小时,将发生闪烁。

    主要就是高频元素与采样频率的不一致然后导致的视觉效果。

    mipmaping采取的就是删除高频信息,根据原来的纹理创建一系列包含高频信息越来越少的纹理,其中每个纹理都是前一个纹理的1/4。

    如一个256x256纹理,我们可以创建一个mip纹理链,纹理的长度和宽度每次都减半,我们可以创建出256x256,128x128, 64x64, 32x32, 16x16, 8x8, 4x4, 2x2, 1x1共9个级别纹理,其中每一个级别纹理图都是前一个的平均滤波。

    之后有了mip纹理表,在对每个三角形进行纹理映射时,根据三角形的面积进行选取哪一个级别纹理合适,原则是纹理图刚好大于三角形在屏幕上的面积(单位为像素)

    公式:mip_ratio = 0级mip纹理面积 / 多边形投影后面积,level = ln(mip_ratio) / ln4

    最后得到的结果level向下取整就是我们需要选择的纹理等级

三线性纹理滤波

    三线性纹理滤波使用双线性插值和mipmapping。

    我们在使用mipmaping选择纹理图时,得到的纹理级别并不是整数,一般是一个小数,这样表示选择的纹理图在两个级别纹理之间,例如我们得到一个结果类似4.3,我们选择等级4和等级5两个纹理图,对于一个纹理坐标u,v,我们在等级4的纹理图中取u,v的双线性插值纹素color4,在等级5的纹理图取u/2,v/2的双线性插值纹素color5。

    之后最终的纹素结果为mip_pixel = (1 - 0.3) * color4 + (0.3) * color5

随机文章
3D图形学总结(六)—背面消除与物体剔除 四元数的一些整理 lua的sort排序 3D图形学总结(四)—透视坐标变换 python爬虫之爬取腾讯新闻
推荐文章