最近策划在测试时,发现在iPhone 7P上,即便是室内场景,帧数也不足60FPS。为了在 iPhone 7P 上实现 60FPS,做了一些优化。这次的优化,基本都和采样相关,所以一起记录一下。

像素采样位置

       这个和效率优化无关,最近有个同事在实现LUT的时候发现了这个情况,所以记录一下。

UE4 iOS 模板测试

       现代GPU普遍有个特点,就是渲染能力不是问题(允许很多drawCall数量),而带宽很成问题。(延迟渲染被TDR/F+取代的主要原因)。节约带宽是现代GPU优化最行之有效的方案。

       UE4,在iOS上,对于深度和模板测试,默认使用 depth32Float_stencil8 格式来存储深度&模板缓冲,这是一个 64bit 的贴图格式。带宽消耗非常大。iOS上并不支持24bit浮点深度,不太清楚苹果为何这样设计。

       首先提供一个新手向简易模式,就是将iOS的深度和模板贴图分离(为iOS添加命令行参数 metalforceseparatedepthstencil ),深度使用 depth32Float 格式,模板使用 stencil8 格式,这样总带宽消耗是 32 + 8 = 40bit。相比 64bit 还是节约不少的。

       接下来提供一个上级模式,这个模式需要改UE4的源码,而且改动不算小。就是,如果项目没有使用模板测试的话,就完全不使用模板缓冲。在将深度和模板贴图分离的基础上,将 stencil attachment 的 pixelFormat 设置为 MTLPixelFormatInvalid 即可。我们并没有阻止 stencil texture 的生成,因为UE4的逻辑实在复杂,害怕哪里检查非空就崩溃了,保证渲染时不使用节省显卡带宽是主要目的。至于运行过程中生成的 stencil texture 的内存消耗,如果场景渲染使用720P,那消耗还不足1m,开销很小。

各向异性过滤

       先记录一下各向异性过滤的。一个贴图,在正对相机时,是清晰的。在相对相机是斜向时,贴图内部的线条就会发生一定程度的失真。而各向异性过滤,解决的就是贴图斜视时纹理内部的失真问题。各向异性过滤便是为了处理这个问题而存在的。也就是说,各向异性过滤和MSAA在目的上都是为了解决失真问题。

       传统的采样一般使用方形采样,而各向异性则使用多边形采样,比如平行四边形采样,采样的平行四边形就是传统采样的方形随着倾斜变换为平行四边形而来。1x的各向异性过滤,最坏时要采样8次(各向异性过滤和采样次数透视后的uv比有关,最坏为各向异性级别 x 8)

Filtering Sample Number
Nearest Point Sampling 1
Bilinear 4
Trilinear 8
Anisotropic Filtering 1X 8
Anisotropic Filtering 2X 16
Anisotropic Filtering 4X 32
Anisotropic Filtering 8X 64
Anisotropic Filtering 16X 128

       可以说,各向异性过滤采样极多,对性能影响非常大。在移动设备上,尽可能少用或者不用。在手机这种小屏高分辨率设备上,基本没必要用。

       请仔细检查材质使用各向异性纹理的情况。我们在排查时,发现室内有个材质使用了各向异性x8的纹理,真是要命。

还是UI

       虽然以前吐槽过UE4 ui的复杂程度,但是没有想到UE4的UI有个缺省设计,就是一旦UI发生旋转,自动使用各向异性过滤。这个设计其实也可以理解,毕竟游戏的UI保证清晰度是很有必要的。我们的某个策划做了个信封,这个信封有旋转,旋转过程中还有动态模糊。这就爆炸了。首先UI都是使用native分辨率,带宽占用不低,旋转时做了各向异性过滤,还有post processing。所以说,UI还是少作死,该用帧动画就做个帧动画,别觉得用程序实现也许更省。