Unity_Shader高级篇_16_Unity Shader入门精要_减少计算复杂度

16.8 减少计算复杂度

16.8.1 Shader的LOD技术
和16.5.2提到的模型的LOD技术类似,Shader的LOD技术可以控制使用的Shader等级。它的原理是,只有Shader的LOD值小于某个设定的值,这个Shader才会被使用,而使用了那些超过设定值的Shader的物体将不会被渲染。
我们通常会在SubShader中使用类似下面的语句来指明该shader的LOD值:

SubShader{
     Tags{"RenderType" = "Opaque"}
     LOD 200
}

我们也可以在Unity Shader的导入面板上看到该Shader使用的LOD值。在默认情况下,允许的LOD等级是无限大的。这意味着,任何被当前显卡支持的Shader都可以被使用。但是,在某些情况下我们可能需要去掉一些使用了复杂计算的Shader渲染。这时,我们可以使用Shader.maximumLOD或Shader.globalMaximumLOD来设置允许的最大LOD值。
unity内置的Shader使用了不同的LOD值,例如,Diffuse的LOD为200,而Bumped Specular的LOD为400。

16.8.2 代码方面的优化
在实现游戏效果时,我们可以选择在哪里进行某些特定的运算。通常来讲,游戏需要计算的对象、顶点和像素的数目排列是对象数<顶点数<像素数。因此,我们应该尽可能地把计算放在每个对象或逐顶点上。例如,在第13章实现高斯模糊和边缘检测时,我们把采样坐标的计算放在了顶点着色器中,这样的做法远好于把它们放在片元着色器中。
而在具体的代码编写上,不同的硬件甚至需要不同的处理。因此,一些普通的规则在某些硬件上可能并不成立。更不幸的是,通常Shader代码的优化并不那么直观,尤其是一些平台上缺少相关的分析器,例如iOS平台。尽管如此,在本节我们还是会给出一些被认为是普遍成立的优化策略,但如果发现在某些设备上性能反而有所下降的话,这并不奇怪。
首先第一点是,尽可能使用低精度的浮点值进行运算。最高精度的float/highp适用于存储诸如顶点坐标等变量,但他的计算速度是最慢的,我们应该尽量避免在片元着色器中使用这种精度进行计算。而half/mediump使用于一些标量、纹理坐标等变量,它的计算速度大约是float的两倍。而fixed/lowp适用于绝大多数颜色变量和归一化的方向矢量,在进行一些对精度要求不高的计算时,我们应该尽量使用这种精度的变量。它的计算速度大约是float的4倍,但要避免对这些低精度变量进行频繁的swizzle操作(如color.xwxw)。还需要注意的是,我们应当尽量避免在不同精度之间的转换,这有可能会造成一定的性能下降。
对于绝大多数GPU来说,在使用插值寄存器把数据从顶点着色器传递给下一个阶段时,我们应该使用尽可能少的插值变量。例如,如果需要对两个纹理坐标进行插值,我们通常会把他们打包在同一个float4类型的变量中,两个纹理坐标分别对应了xy分量和zw分量。然而,对于PowerVR平台来说,这种插值变量是非常廉价的,直接把不同的纹理坐标存储在不同的插值变量中,有时反而性能更好。尤其是,如果在PowerVR上使用类似tex2D(_MainTex,uv.zw)这样的语句来进行纹理采样,GPU就无法进行一些纹理的预读取,因为它会认为这些纹理采样是需要依赖其他数据的。因此,如果我们特别关心游戏在PowerVR上的性能,就不应该把两个纹理坐标打包在同一个四维变量。
尽可能不要使用全屏的屏幕后处理效果。如果美术风格实在是需要使用类似Bloom、热扰动这样的屏幕特效,我们应该尽量使用fixed/lowp进行低精度运算(纹理坐标除外,可以使用half/mediump)。那些高精度的运算可以使用查找表(LUT)或者转移到顶点着色器中进行处理。除此之外,尽量把多个特效合并到一个Shader中。例如,我们可以把颜色校正和添加噪声等屏幕特效在Bloom特效的最后一个Pass中进行合成。还有一个方法就是使用16.8.3中介绍的缩放思想,来选择性地考起特效。

·尽可能不要使用分支语句和循环语句。
·尽可能避免使用类似sintanpow、lof等较为复杂的数学运算。我们可以用查找表来作为代替。
·尽可能不要使用sidcard操作,因为这会影响硬件的某些优化。

16.8.3 根据硬件条件进行缩放
我们首先保证游戏最基本的配置可以在所有的平台上运行良好,而对于一些具有更高表现能力的设备,我们可以开启一些更“炫酷”的效果,比如使用更高的分辨率,开启屏幕后处理特效,开启粒子效果等。

Unity官方手册的移动平台优化实践指南(http://docs.unity3d.com/Manual/MobileOtimizationPracticalGuide.html)一文给出了一些针对移动平台的优化技术,包括渲染和图形方面的优化,以及脚本优化等。手册中另一个针对图像性能优化的文档是优化图像性能(http://docs.unity3d.com/Manual/OptimizingGraphicsPerformance.html)一文,在这个文档中,Unity给出了常见的性能瓶颈以及一些相应的优化技术。
在SIGGRAPH 2011上,Unity进行了一个关于移动平台上Shader优化的演讲(http://blogs.unity3d.com/2011/08/18/fast-mobile-shaders-talk-at-siggraph/)。字在这个演讲中,作者给出了各个主流移动GPU的架构特点,并给出了相应的shader优化细节,还结合了真实的Unity游戏项目来进行实例学习。在Unite 2013会议上,Unity呈现了一个名为针对移动平台优化Unity游戏的演讲。在GDC 2014 上,Unity展示了如何使用内置的分析器分析移动平台的游戏性能,可以在Youtube上找到相应的视频。

猜你喜欢

转载自blog.csdn.net/qq_39710961/article/details/79882174