Shader优化

介绍一些优化Shader的方法。

一 内存优化

1 LOD/可控的SubShader加载

Shader LOD的动态加载与释放:不同级别的Shader LOD,动态加载当前需要使用的Shader LOD(subshader),减少shaderlab内存占用(需要修改引擎源码)。

2 运行时压缩

如果有条件利用时间换空间的话。

默认的runtime的shader创建过程
在transfer中会将实际的shader code进行解压,并在之后parse的过程中创建的subprogram中进行保存 (programCode 字段)。

压缩(LZ4HC)保存在subprograme内的shader code,在compile到gpu时再解压(Unity默认情况下保存的是已经解压过的shader code)。

节约内存,但是可能warmup或直接compile gpu program时的时间开销增大。

3 Shader变体优化

二 ALU计算优化

精简算法

  • 移动平台最好禁用Standard材质
  • 特别是全屏绘制的物体需要尽量简化Shader,比如空气墙。

降低浮点数精度

  • 在移动平台下,GPU可在执⾏⼀个float操作的同等周期内,执⾏2个half操作。尤其是屏占⽐较⾼、半透明物件所⽤的shader,优化的收益较⾼。
  • 通过Xcode性能分析工具可以得到有效提示

复杂函数

  • Transcendental mathematical functions (such as pow, exp, log, cos, sin, tan) are quite resource-intensive, so avoid using them where possible on low-end hardware. Consider using lookup textures as an alternative to complex math calculations if applicable.
  • Avoid writing your own operations (such as normalize, dot, inversesqrt). Unity’s built-in options ensure that the driver can generate much better code.
  • Remember that the Alpha Test (discard) operation often makes your fragment shader slower.

分支循环

  • 为了合批⽽添加if/else,如果实际效果不明显,建议使⽤Shader变体来解决

其他

  • 移除Material中没有使用到的属性
  • 禁止一些不必要的操作或用替代方案,比如GrabPass
  • 适配中低端手机考虑减少纹理采样次数

参考