求知若饥,虚心若愚
本章将会对 Unity 5 进行的一些重要更新(仅关注 Shader 方面的更新)进行解释,来帮助读者加深对 Unity Shader 的理解。
场景“更亮了”
Unity 5 之前的一些 Shader 源码,往往会在计算漫反射时发现类似下面的代码:
1 | // Unity 5 之前的 shader 经常包含了类似下面的代码, |
Unity 5 之前的 Shader 中需要乘以 2 是一个历史遗留原因,并最终在 Unity 5 中得到了修正。
表面着色器更容易“报错了”
这些报错信息通常是值 Shader 中的数学指令或插值寄存器的数目超过了限制,并提示需要使用更高的 Shader Model,如 SM 3.0。
这是因为 Unity 5 的表面着色器在背后进行了更多的计算。这些新添加的计算和插值寄存器通常是为了计算阴影、雾效、非同一缩放模型的法线变换矩阵。
一种解决方法是直接使用更高的 Shader Model,因为 Unity 默认的 Shader Model 版本为 2.0:
1 | #pragma target 3.0 |
另一个方法是减少表面着色器背后的计算,这可以通过表面着色器的编译指令来实现。例如指明不需要为该物体计算阴影纹理坐标(不接收阴影)、光照纹理坐标以及雾效:
1 | #pragma surface surfaceFunction lightModel noshadow nolightmap nofog |
当家作主:自己控制非统一缩放的网格
在 Unity 5 之前的版本中,我们并不需要在 Shader 中考虑非统一缩放带来的种种影响,因为传到 Shader 中的数据已经不存在非统一缩放了。因为之前的版本会在 CPU 中把涉及非统一缩放的模型变换成统一缩放的模型,会在 CPU 中再创建一个和非统一缩放模型空间大小相同,但只包含统一缩放的模型。旧 Shader:
1 | // #define SCALED_NORMAL (v.normal * unity_Scale.w) |
这种做法的好处是,我们不需要在渲染中考虑非统一缩放的影响。他的缺点是,CPU 的计算消耗会更大,而且需要占用更多内存空间来存储这些重新缩放的模型。
Unity 5 抛弃了之前的做法。如果我们需要在顶点/片元着色器中变换顶点法线,就需要时刻小心非统一缩放的影响,以及需要对变换后的法线进行手动归一化的操作。
固定管线着色器逐渐退出舞台
固定管线着色器是在可编程着色器出现之前,GPU 大量使用的着色器形式。他的工作方式就像是一个包含了很多开关和配置的黑箱子,我们可以通过开启或关闭某些功能来让 GPU 进行相应的渲染。
截止到 Unity 5.2 版本,所有固定管线着色器都会在导入时被转换成真正的顶点/片元着色器,并且已经支持所有平台,包括游戏机平台。