在 Unity 中,可使用 HLSL 编程语言来编写着色器程序。
Unity 最初使用 Cg 语言,因此会使用 Unity 某些着色器关键字的名称 (CGPROGRAM
) 和文件扩展名 (.cginc
)。Unity 已不再使用 Cg,但仍支持这些关键字和文件扩展名。请注意,所有着色器程序代码都必须是有效的 HLSL,即使代码使用与 Cg 相关的关键字和文件扩展名也如此。
使用 HLSLPROGRAM
与使用 CGPROGRAM
之间的唯一区别在于 Unity 在编译着色器程序时自动包含的文件。这是为了向后兼容。有关更多信息,请参阅内置着色器 include 文件。
HLSL 语言本身有两种语法:“旧版”的 DX9 样式语法以及更现代的 DX10+ 样式语法。
不同之处主要在于纹理采样函数的工作方式:
sampler2D
、tex2D()
和类似函数。此语法适用于所有平台。Texture2D
、SamplerState
和 .Sample()
函数。由于纹理和采样器在 OpenGL 中_不是_不同对象,因此该语法的某些形式在 OpenGL 平台上无效。在 Unity 中,可使用预定义宏来声明和采样纹理,从而避免发生 HLSL 语法平台支持问题。Unity 将根据编译着色器的目标平台,将这些宏扩展为最合适的语法。
不同平台使用不同的着色器编译器来编译着色器程序,如下所述:
可以使用预定义着色器宏来确定 Unity 在使用哪个编译器(例如,使用仅一种编译器支持的 HLSL 语法)或解决编译器错误。
着色器编译涉及几个步骤。首先,需要对着色器源代码进行预处理。默认情况下,Unity 使用平台编译器的预处理器来执行这一步;但是,您可以选择覆盖它,而使用 Unity 的缓存着色器预处理器来执行预处理。缓存着色器预处理器比平台编译器使用的默认预处理器最多快 25%。
缓存着色器预处理器缓存中间预处理数据,可以加速着色器导入和编译。编辑器重用这些缓存数据,只需要在内容更改时解析 include 文件。这使得编译同一着色器的多个变体更加高效。当项目中的着色器使用大量常见 include 文件时,启用缓存着色器预处理器具有最明显的效果。
请注意,缓存着色器预处理器是实验性的功能;仍处于积极开发阶段。您可以在 Unity 论坛上提供与此实验性功能相关的反馈。
您可以使用 Editor settings 窗口的 Shader Compilation 部分中的 Caching Shader Preprocessor (Experimental) 复选框来启用或者禁用缓存着色器预处理器。也可以在 C# 脚本中使用 EditorSettings.cachingShaderPreprocessor API 启用或禁用此功能。