图形1.3 纹理的优化方式
纹理的优化方式
纹理循环模式(Wrap Mode)
纹理循环模式决定了纹理采样的uv值在[0,1]以外的表现。
包括但不限于有:Repeat,Clamp,Mirror,Border。
它们各自的表现为:
纹理过滤(Texture Filter)
纹理过滤(texture filter),用来降低高几何精度下物体观察角度造成图形折叠的“纹理失真”采用的一种技术。
当这种情况发生时,纹理就会变得模糊或者错位,因此我们引入了这种技术来平滑纹素(texel,纹理图形的基本单位)和像素之间的对应,这种技术就叫做纹理过滤。
不同的过滤模式(filter mode),计算复杂度不一样,效果也不同。
其过滤模式最常见的包括:最近点采样(Nearest),双线性过滤(Biliner),三线性过滤(Trilinear)。
最近点采样:最容易理解的一个。由于每个像素的纹理坐标,刚好对应贴图上的一个采样点纹素,所以最近点采样就是直接取最接近的纹素进行采样。如果纹理大小和被贴合的三维模型大小差不多时,这种方法会比较有效和快捷,但是如果大小不同,纹理就会变得矮胖、变形或者模糊,容易出现块状的像素,使得处理出的效果很差。
双线性过滤:双线性过滤以像素对应的纹理坐标为中心,采集这个坐标周围的4个纹素的像素,再取平均,最后以这个平均值作为采样值。这样过滤后的像素则会更加平滑,至少不会出现块状像素了。
但双线性过滤只作用于一个MipMap Level,它选取纹素和像素之间大小最接近的那一层MipMap进行采样。这意味着如果和像素匹配大小的纹素大小在两层MipMap Level之间的话,双线性过滤的效果就有限了,因此有了三线性过滤。
三线性过滤:三线性过滤以双线性过滤为基础。会对像素大小于纹素大小最接近的两层MipMap Level分别进行双线性过滤,然后再对两层得到的结果生成线性插值。在各向同性的情况下,三线性过滤能获得很不错的效果。
其他过滤模式:
各向异性过滤(Anisotropic Filtering):按比例在各方向上采样不同数量的点来计算最终的结果。
立方卷积插值(Bicubic):取周围邻近的16个纹素的像素,然后做插值计算,不过并非是线性插值而是每次用4个做一个三次的插值。
光滑曲线插值(Quilez):在立方卷积插值和双线性过滤的一个折中效果,将纹理坐标带入到双线性插值前额外做了一步处理。
MipMap
纹理采样的时候,在去对缩小的图像采样时就会走样失真,像素会丢失或闪烁,远处会出现摩尔纹,近处则会出现锯齿。
糟糕的采样:
我们确实能够按照处理抗锯齿的方式去处理纹理走样,使用超采样确实能够让图像的结果更加接近,但却要为此耗费大量的性能开销,这明显本末倒置了:
因此如果我们不提升像素的采样频率,就只能去选择降低纹理的频率,所以我们引入了MipMap技术。
什么是MipMap技术?
MipMap就是为一张纹理预处理生成一堆每个图像的高度和宽度是前一级别2的幂的mipmap图像。举个例子一张1024*1024的纹理,生成的MipMap图像会新产生512*512、256*256、128*128、64*64、32*32、16*16、8*8等这堆往下分辨率递减的纹理。靠近相机的图像使用高MipMap Level,远离相机的图像则使用低MipMap Level。MipMap图像不必是正方形的,它生成的新一级纹理总是上一级的1/4大小,总体在储存空间中多消耗1/3的空间。
但是屏幕像素可能会导致过渡模糊,因为我们仍然没有解决各向异性的问题,一个像素格上可能覆盖了大量的纹理,它可能是一个不怎么规则而且非常长的四边形,在MipMap中,那些被平均过的纹理,就不能得到准确的结果,因此我们才会有了上面提到的各向异性过滤,因此可以说,虽然采样数越多效果越好,但是具体使用时要综合考虑性能问题。
各向异性的采样问题:
常用的纹理优化方式
对于CPU来说,我们要尽可能减少调用DrawCall次数,也就是一次性要传多个纹理过去。具体的做法就是把很多纹理都做成一张纹理的图集,这样我们采样的时候就去从这一张纹理图集里面采样;或者使用一个纹理数组,把整个纹理数组一起传过去,从而减少DrawCall的调用。
对于GPU来说,我们则可以选择将纹理进行压缩,去降低传输纹理所需要带宽,这样整个传输数据的耗时也能减少,对内存的使用效率便会提高。
参考链接
GAMES101-现代计算机图形学入门-闫令琪-Lecture 09 Shading 3 (Texture Mapping Cont.)