在讨论纹理坐标和采样时,你可能已经注意到了,没有一种纹理映射object能够做到使纹理图上的元素与渲染到屏幕上的像素之间一一对应。Camera位于textured object任意的位置,并从任意的角度观看。想像下这种情形,camera相对textured object进行放大,Rasterizer阶段确定哪些pixels会发送到pixel shader中,并对纹理坐标进行插值计算,此时纹理坐标表示的位置在纹理中的元素之间。换句话说,就是以比纹理图片本身分辨率更高的方式来渲染纹理。Texture filtering的目的就是确定哪些颜色值会被用于pixels中,因为这些pixels无法在纹理中直接一一对应的找到。
上面所描述的情形就是magnification,在这种情况下,需要渲染的pixels比纹理图中包含的元素要多。Direct3D支持三种filtering用于确定这些pixels的颜色值:point filtering,linear interpolation,以及anisotropic filtering(点滤波,线性插值,和各向异性滤波)。
Point filtering是计算速度最快的filtering选项,但图片的质量也是最低的。Point filtering也称为nearest-neighbor(邻近取样) filtering,只是简单的使用纹理中与pixel中心最接近的坐标颜色值。如图5.5,左图中显示了使用point filtering产生的blocky-looking(块状)图片。
图5.5 The results of point filtering (left) and bilinear interpolation (right) on a magnified texture.
(Texture by Reto Stöckli, NASA Earth Observatory.)
Linear Interpolation是一种比point filtering质量更高的filtering选项,在linear interpolation中颜色值是通过相邻的两个纹理元素插值计算出来的。对于2D textures,更准确的说应该叫bilinear interpolation(双线性插值),因为要在水平和垂直两个方向都进行插值。使用双线性插值,首先要确定围绕pixel中心的四个纹理元素,再沿着U轴执行两次一维的线性插值,然后沿着V轴执行第三次插值,就可以产生最终的颜色值。图5.5中,右边的图片是在相同的放大纹理中使用双线性插值的结果,可以明显的看出比point filtering更平滑。
Anistropy是指,在一个相对camera处于倾斜角度的表面上,投影一个纹理产生的变形程度。Anistropic filtering(各向异性滤波)就是用于减小这种变形程序,并改善渲染的输出结果。这是一种计算成本最大的filtering选项,但是产生的结果却是质量最好的。图5.6展示了使用和不使用anisotropic filtering进行纹理映射的对比效果。
图 5.6 A mapped texture with bilinear filtering (top) and anisotropic filtering (bottom).
Minification与magnification正好相反,应用于pixel对应于多个纹理元素的情况,也就是要渲染的pixels比纹理元素要少。当camera与纹理表面距离变的更远时就会发生这种情况,此时Direct3D必须选择合适的颜色值,与magnification使用同样的filtering选项,但是这些filtering选项在minification中要更复杂。例如,使用linear interpolation filtering选项,与magnification一样先确定围绕pixel中心的四个纹理元素。但是,其中的纹理元素(一个pixel所对应的多个颜色值)都会被忽略,而且不会参与计算最终的颜色。这样就会产生多余的东西而降低渲染质量。你可能会想到使用纹理平均值的方法产生更好的效果。但是,这样的计算方法是基于down-sampled texture的分辨率,而且有任意多个缩放级别的分辨率可以计算。建立这么多的级别是不切实际的,但是这种方法,可以通过一种称为mipmapping的技术提前计算来实现。
Mipmaps是原始纹理图的小分辨率的版本,通常是提前计算好并存储在同一个文件中。每一个mip-level都是由上一个渐进的除以2 ,直到缩小为一个1×1的纹理。图5.7中显示了尺寸为512×256的Earth纹理图与对应的9个mip-levels。
图5.7 A mipmapped Earth texture with nine mip-levels. (Original texture from Reto Stöckli, NASA
Earth Observatory. Additional texturing by Nick Zuccarello, Florida Interactive Entertainment Academy.)
使用mipmaps时,需要两步才能生成最终的颜色值。第一步,mip-level必须选择minification或者magnification。第二步,所选择的mip-level要能够通过滤波生成一个颜色值。
可以使用point或linear filtering选择一个mip-level。Point filtering只是简单选择最接近的mip-level,而linear filtering会选择与期望尺寸最接近的一大一小的两个mipmaps。然后通过point,linear或者anisotropic filtering方法对选中的mip-level进行采样。如果使用linear filtering选择了两个相邻的mipmaps,那么两个mipmaps都会被采样,并把使用他们插值作为最终的结果。这种技术能够生成最高质量的结果。最后需要注意的是,虽然mipmapping改善了渲染质量,但也增加了33%的内存需求。
回顾一下TextureMapping.fx(见列表5.7)中的SamplerState对象,有一个Filter成员变量并被赋值为MIN_MAG_MIP_LINEAR。该变量值表明对于minification,magnification,和mip-level sampling都使用线性插值进行采样。表5.1列出了各种filtering排列的例子。在MSDN网站的Direct3D文档中可以查看完整的列表。
列表5.7 The Sampler Object Declaration from TextureMapping.fx
SamplerState ColorSampler { Filter = MIN_MAG_MIP_LINEAR; AddressU = WRAP; AddressV = WRAP; };
表5.1 Texture Sampling Filter Options