《枪神纪》贴图滤波方式实践

发表于2015-08-24
评论0 4.8k浏览

摘要

       本文主要介绍了贴图缩小采样滤波(Texture Minification Filtering)的方式与实现,并结合枪神纪的优化实践,介绍如何去选择合适的滤波方式。

背景

       枪神纪的玩家配置中,使用集成显卡(含核芯显卡)与低端显卡的玩家占据了相当大的份额,我们一直以来在不遗余力的减少Draw Call,优化Shader,做大量的LOD等等工作去减轻显卡的压力,却忽略了贴图滤波方式对这部分的显卡也有很大的影响。

D3D9中的贴图滤波方式

       贴图往往并不是1:1的投影到物体表面并最终呈现到实际的屏幕像素上,当最后呈现到屏幕中的尺寸比贴图实际尺寸大的时候,此时需要对贴图进行放大(Texture Magnification),反之需要缩小(Texture Minification),贴图放大采样的时候如果不经处理,则会出现马赛克等方块等情况,如果贴图缩小采样的时候不经处理,那么就会产生锯齿(Texture Alias)[1]。因此,贴图滤波就变得非常必要,而对于贴图缩小采样(Texture  Minification )来说,Mip Map是一个廉价的方式去完成一次采样--只是一次数组查找即可[2]。然而,最终投影到屏幕上的贴图的采样率是随着像素变化而变化的,是由场景的几何形状,它的旋转轴向,贴图映射的算法,相机的位置等等因素决定的。因此,实际的贴图采样率并不是固定的,即使对Mip Map采样之后,还需要进行各种滤波才行。

Texture Mipmap的生成

       Texture Mipmap是指对原始贴图进行逐级预处理,每一级是上一级的1/4大小(长宽各一半),预处理的方法通常是一个简单的平均。但是对于贴图中所存储的值与最终的颜色值不是线性关系,例如法线贴图,那么简单的平均会产生错误的效果[3]。但是,视觉往往没有那么敏感,因此,在UE3中也没有对法线贴图使用单独的Mip Map生成算法,只是提供了一系列锐化(Sharpening)的Mipmap生成算法,供用户自己选择。

Texture Fillrate硬件指标

       Texture Fillrate是显卡硬件中经常出现的一个概念,也是相对模糊的概念,计算的方式为:

贴图填充率=TMU的每周期处理能力 X TMU数目 X Clock.  [3]

然而,上面的处理是指在没有任何滤波的情况下的速度,在实际情况中,滤波的方式往往不会一成不变,贴图的格式也各不相同。同时,影响贴图性能的最主要因素是cache的命中率,这也是大贴图为什么没有小贴图高效的原因,因为小的贴图能够更好的Fit进显卡的Texture Sampler Cache,对于顺序读取的贴图来说,贴图命中率也就更高,速度也更快[6]。

       因此,厂商宣传的贴图的填充率的大小并不能绝对代表一个显卡对于贴图的处理能力。在实际的测试过程中,我们发现即使7600GT的贴图处理能力并不如Intel HD Graphics,即使7600GT列出的贴图填充率更高。

Texture Filtering与硬件消耗

D3D9提供了几种贴图滤波方式(None,Point,Linear,Anistropic),各自分别对应了贴图放大时采用的滤波算法(Mag Filter),贴图缩小时采用的滤波算法(Min Filter),以及Mip Map的滤波算法(Mip Filter)[4]。使用MipMap虽然会增加33%的内存消耗,但是却因为采样更小的贴图,提高了贴图的Cache的命中率,因此往往能取得更好的性能[8]。所以在UE3中,把采样方式组合进行了一次简单的封装,默认都使用了MipMap。

    封装的滤波方式

MinFilter

MagFilter

MipFilter

SF_AnisotropicLinear

D3DTEXF_ANISOTROPIC

D3DTEXF_LINEAR

D3DTEXF_LINEAR

SF_AnisotropicPoint

D3DTEXF_ANISOTROPIC

D3DTEXF_LINEAR

D3DTEXF_POINT

SF_Trilinear

D3DTEXF_LINEAR

D3DTEXF_LINEAR

D3DTEXF_LINEAR

SF_Bilinear

D3DTEXF_LINEAR

D3DTEXF_LINEAR

D3DTEXF_POINT

SF_Point

D3DTEXF_POINT

D3DTEXF_POINT

D3DTEXF_POINT

       在D3D9里, MipFilter只支持D3DTEXF_NONE, D3DTEXF_POINT和D3DTEXF_LINEAR。D3DTEXF_NONE是指不用mip map,D3DTEXF_POINT是在最接近的mip level做一次sampling, D3DTEXF_LINEAR是对两个nearest level各做一次sampling, 再linear blend。 因为通常结合UV两个方向的linear sampling,所以常叫做trilinear sampling。trilinear sampling的目标是为了减少两个Mip交界处的断裂的效果。

在Intel平台上SF_Point和SF_Bilinear消耗相同,SF_Trilinear在较新的显卡上也能取得一样的消耗,这个结论来自Intel的白皮书[5], Nvidia平台也在内部交流的邮件中提到了相同的消耗:

       可以看出,使用Point,Bilinear,Trilinear往往是相同的性能损耗,但是,一旦使用了Anisotropic之后,贴图采样器的性能就明显下降,那么Anisotropic Filtering到底是一个什么技术呢?

Anisotropic Filtering

         Anisotropic又称为各向异性,具体表现在当贴图大的投影区域是一个一个陡的梯形时,远处的贴图会出现模糊的情况。原因则是因为,这是一个斜长型投影区域,贴图的UV投影长度相差较大,而MipMap又只有长宽相等的一级,因此导致了满足一个方向的Mip时,另外一个方向却不满足。

Rip Mapping是解决这个问题的一个方案[6],Rip Mapping的做法就是再实际生成一套半长宽的Mip来去避免这个问题,例如下图生成1x4,2x4这样的非正方形Mip等级,但在实际使用过程中,Rip Mapping几乎没有在游戏引擎中使用,也许是因为他需要更多的空间去存储这些非正方形Mip。

Anisotropic Filtering效果与实现

         Anisotropic Filtering在枪神纪实际游戏中的效果如下:

         然而AF并没有一个标准的实现算法,不同的厂商的AF算法各不相同,甚至每一代显卡的AF算法也可能不一样,Intel有一个Free Patent里面描述了Intel的实现方法,从中我们可以得知主要的流程。

       首先需要将一个实际的投影像素细分成若干个SubPixel,然后根据SubPixel投影在贴图上的Foot Print对贴图进行采样, 最后对采样回来的Sub Pixel的Sample进行一次滤波。

       

       

枪神纪的实践

         UE3默认对贴图使用了AF滤波,在低端显卡上给我们带来了严重的性能损耗,而且如果一个Pass里使用了多张贴图的AF时(如下图: 多重纹理混合的地表),这个消耗更加大。

         在Intel HD Graphics 1000显卡下,通过GPA中调整每个贴图的滤波方式从Aniso到Linear,实际读取的字节大小的关系大概如下表所示:

 

读取的像素

总绘制耗时

剩余Aniso贴图

全部Aniso

2983904

2226

6

一张贴图Linear

2155968

1792

5

两张贴图Linear

1444448

1344

4

三张贴图Linear

858848

925

3

四张贴图Linear

860320

925

2

五张贴图Linear

511808

576

1

六张贴图Linear

512704

589

0

       我们发现了当Aniso的贴图数目超过1张之后,就会有一个上升,但是在一张Aniso和0张Aniso是一样的效果的,这大概是和硬件内部的TMU的数目相关,但是当我们的Aniso的贴图数目超过了3张之后,那么每多一张Aniso,都会导致明显的影响。

枪神纪的权衡

       在实际使用过程中,我们保留了对光图使用Aniso的滤波方式,因为远处的光图经常会出现Aniso的实际需求,例如下面组图,有使用Aniso和没有使用Aniso的贴图效果对比:

两幅效果图做Diff之后:

       我们看到远方的光图效果变差,因此,我们对光图保留了Aniso的滤波,平衡了效率和效果。

参考

[1] Real Time Rendering 3rd Edition, Page 157-170, Image Texturing.

[2] Physically Based Rendering 2nd Edition, Page 528, Mip Mps.

[3] Real Time Rendering 3rd Edition, Page 271-275, Mipmapping BRDF and Normal Maps.

[4] D3DTEXTUREFILTERTYPE Enumeration: http://msdn.microsoft.com/en-us/library/windows/desktop/bb172615(v=vs.85).aspx

[5] Intel Graphics Media Accelerator Developer's Guide : http://software.intel.com/sites/default/files/m/d/4/1/d/8/Intel_Integrated_Graphics_Performance_Developer_s_Guide_v2.6.7.pdf

[6] Anisotropic filtering technique: http://en.wikipedia.org/wiki/Anisotropic_filtering

[7] Anisotropic filtering technique, United States Patent 6816167: http://www.freepatentsonline.com/6816167.html

[8] G80 Programming Guide, Page 28, 3.5 Texturing: http://developer.download.nvidia.com/GPU_Programming_Guide/GPU_Programming_Guide_G80.pdf

 

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引