ShaderLab 着色器描述了在 Material Inspector 中显示的属性,包含用于不同图形硬件的多个着色器实现,并配置固定函数硬件状态。可编程着色器(如顶点和片元程序)只是整个 ShaderLab 的着色器概念的一部分。如需了解着色器的更多信息和介绍,请参阅着色器教程。本页将概要说明低级别硬件着色器的__着色器程序__。
如果要编写与光照交互的着色器,请参阅表面着色器文档。如需查看一些示例,请参阅顶点和片元着色器示例。本页的其余部分假设着色器不与 Unity 光源(例如特殊效果和后期处理效果)交互。
着色器程序用 HLSL 语言编写,在着色器文本中嵌入代码片段(在 Pass 命令中的某个位置)。着色器程序通常如下所示:
  Pass {
        // ...常规通道状态设置 ...
      
        CGPROGRAM
        // 此代码片段的编译指令,例如:
        #pragma vertex vert
        #pragma fragment frag
      
        // Cg/HLSL 代码本身
      
        ENDCG
        // ...通道设置的剩余部分 ...
    }
HLSL 程序代码片段写入到 CGPROGRAM 和 ENDCG 关键字之间,或者 HLSLPROGRAM 和 ENDHLSL 之间。后一种形式不会自动包含 HLSLSupport 和 UnityShaderVariables 内置头文件。
在代码片段的开头,可使用 #pragma 语句的形式提供编译指令。下表列出的指令可指示要编译的着色器函数:
| 语句 | 功能 | 
|---|---|
| #pragma vertex name | 作为顶点着色器来编译函数 name。 | 
| #pragma fragment name | 作为片元着色器来编译函数 name。 | 
| #pragma geometry name | 作为 DX10 几何着色器来编译函数 name。如下表中所述,此选项会自动开启#pragma target 4.0。 | 
| #pragma hull name | 作为 DX11 外壳着色器来编译函数 name。如下表中所述,此选项会自动开启#pragma target 5.0。 | 
| #pragma domain name | 作为 DX11 域着色器来编译函数 name。如下表中所述,此选项会自动开启#pragma target 5.0。 | 
| 语句 | 功能 | 
|---|---|
| #pragma target name | 设置要编译到的着色器目标。有关更多信息,请参阅着色器编译目标文档。 | 
| #pragma require feature ... | 对着色器需要的 GPU 功能进行精细控制。有关更多信息,请参阅着色器编译目标文档。 | 
| #pragma only_renderers space separated names | 仅为给定的渲染器编译着色器。默认情况下,将为所有渲染器编译着色器。 | 
| #pragma exclude_renderers space separated names | 不为给定渲染器编译着色器。默认情况下,系统会为所有渲染器编译着色器。 | 
| #pragma multi_compile ... | 用于处理多个着色器变体。 multi_compile着色器的未使用变体会包含在游戏构建中。 | 
| #pragma multi_compile_local ... | 此语句类似于 multi_compile,但是枚举的关键字为本地关键字。请参阅编写多个着色器程序变体:关键字限制文档以了解更多信息。 | 
| #pragma shader_feature ... | 用于处理多个着色器变体。 shader_feature着色器的未使用变体不会包含在游戏构建中。 | 
| #pragma shader_feature_local ... | 此语句类似于 shader_feature,但是枚举的关键字为本地关键字。请参阅编写多个着色器程序变体:关键字限制文档以了解更多信息。 | 
| #pragma enable_d3d11_debug_symbols | 为针对 DirectX 11 编译的着色器生成调试信息。这将允许您通过 Visual Studio 2012(或更高版本)图形调试器来调试着色器。 | 
| #pragma hardware_tier_variants renderer name | 针对每个可以运行所选渲染器的硬件层,生成每个由系统编译的着色器的多个着色器硬件变体。 | 
| #pragma hlslcc_bytecode_disassembly | 将反汇编的 HLSLcc 字节码嵌入到转换的着色器中。 | 
| #pragma disable_fastmath | 启用涉及 NaN 处理的精确 IEEE 754 规则。当前这仅影响 Metal 平台。 | 
| #pragma glsl_es2 | 在 GLSL 着色器中进行设置以生成 GLSL ES 1.0(OpenGL ES 2.0),即使着色器目标为 OpenGL ES 3 也是如此。 | 
| #pragma editor_sync_compilation | 强制进行同步编译。这仅影响 Unity Editor。 | 
| #pragma enable_cbuffer | 使用 HLSLSupport 的 CBUFFER_START(name)和CBUFFER_END宏时,即使当前平台不支持常量缓冲区,也要发出cbuffer(name)。 | 
每个代码片段必须至少包含一个顶点程序和一个片元程序,因此需要使用 #pragma vertex 和 #pragma fragment 指令。
以下编译指令不执行任何操作,因此可以安全删除:
#pragma glsl#pragma glsl_no_auto_normalization#pragma profileoption#pragma fragmentoption.Unity 仅在着色器文件中支持 #pragma 指令,而在 include 语句中不支持。
Unity 支持多种渲染 API(例如 Direct3D 11 和 OpenGL),默认情况下,Unity 将所有着色器程序编译到所有支持的渲染器中。您可以使用 #pragma only_renderers 或 #pragma exclude_renderers 指令指示要编译的渲染器。如果您使用的一些着色器语言功能在某些平台上无法实现,这样做将非常有用。支持的渲染器名称包括:
| 语句 | Renderer | 
|---|---|
| d3d11 | Direct3D 11/12 | 
| glcore | OpenGL 3.x/4.x | 
| gles | OpenGL ES 2.0 | 
| gles3 | OpenGL ES 3.x | 
| metal | iOS/Mac Metal | 
| vulkan | Vulkan | 
| d3d11_9x | Direct3D 11 9.x 功能级别,通常在 WSA 平台上使用 | 
| xboxone | Xbox One | 
| ps4 | PlayStation 4 | 
| n3ds | Nintendo 3DS | 
| wiiu | Nintendo Wii U | 
在以下示例中,代码行仅会将着色器编译到 D3D11 模式:
# pragma only_renderers d3d11