着色器代码需要执行的计算和处理越多,它对游戏性能的影响就越大。例如,支持每种材质的颜色可以使着色器更加灵活,但如果始终将该颜色设置为白色,则会对屏幕上渲染的每个顶点或像素执行无用的计算。
计算的频率也会影响游戏的性能。通常,与顶点数(顶点着色器执行次数)相比,渲染的像素数会更多(因此像素着色器执行次数也更多),而渲染的顶点数比渲染的对象更多。在可能的情况下,可将计算从像素着色器代码移动到顶点着色器代码中,或者将它们完全移出着色器并在脚本中设置值。
表面着色器非常适合编写与光照交互的着色器。但是,它们的默认选项已调整为涵盖大量的一般情况。可针对特定情况调整这些选项以使着色器运行速度更快,或至少让着色器变得更小巧:
approxview
指令使视图方向按照顶点(而不是按像素)进行标准化。这是近似值,但通常足够好。halfasview
速度更快。半矢量(光照方向和视图矢量之间)按照顶点进行计算和标准化,并且光照函数接受半矢量作为参数,而不是视图矢量。noforwardadd
使着色器仅完全支持前向渲染中的单方向光。其余的光源仍然可提供每顶点光源或球谐函数光源的效果。这样可以使着色器更小并确保它始终在一个通道中渲染,即使存在多个光源也是如此。noambient
在着色器中禁用环境光照和球谐函数光源。这样可以稍稍提高性能。用 Cg/HLSL 编写着色器时,有三种基本数字类型:float
、half
和 fixed
(请参阅数据类型和精度)。
为获得良好性能,请始终使用尽可能低的精度。这在移动平台(如 iOS 和 Android)上尤为重要。重要的经验法则如下:
float
精度。half
精度。仅在必要的情况下再提高精度。fixed
精度。实际上,具体应该使用哪种数字类型取决于平台和 GPU。一般来说:
float
精度进行所有计算,因此 float/half/fixed
最终产生完全相同的结果。这可能会使测试变得困难,因为更难以确定 half/fixed 精度是否真正够用,因此请始终在目标设备上测试着色器以获得准确的结果。half
精度。这种精度通常速度更快,并且使用更少的性能来执行计算。Fixed
精度通常仅对于较旧的移动端 GPU 有用。大部分新款 GPU(可运行 OpenGL ES 3 或 Metal 的 GPU)在内部以相同方式来处理 fixed
和 half
精度。有关更多详细信息,请参阅数据类型和精度。
固定函数 AlphaTest(或者其可编程的等效函数 clip()
)在不同平台上具有不同的性能特征:
在某些平台(主要是 iOS 和 Android 设备的移动端 GPU)上,使用 ColorMask 省略一些通道(例如 ColorMask RGB
)可能是资源密集型的操作,所以除非绝对需要,否则请不要使用。