Version: 2020.1
支持 DX11/OpenGL Core 曲面细分的表面着色器
顶点和片元着色器示例

编写顶点和片元着色器

ShaderLab shaders describe properties that the Material Inspector displays, contain multiple shader implementations for different graphics hardware, and configure fixed function hardware states. Programmable shaders like vertex and fragment programs, are just a part ShaderLab’s shader concept. This page outlines the low-level hardware shaders shader programs.

如果要编写与光照交互的着色器,请参阅表面着色器文档。如需查看一些示例,请参阅顶点和片元着色器示例。本页的其余部分假设着色器不与 Unity 光源(例如特殊效果和后期处理效果)交互。

着色器程序用 HLSL 语言编写,在着色器文本中嵌入代码片段(在 Pass 命令中的某个位置)。着色器程序通常如下所示:

  Pass {
        // ...常规通道状态设置 ...
      
        CGPROGRAM
        // 此代码片段的编译指令,例如:
        #pragma vertex vert
        #pragma fragment frag
      
        // Cg/HLSL 代码本身
      
        ENDCG
        // ...通道设置的剩余部分 ...
    }

HLSL 代码片段

HLSL 程序代码片段写入到 CGPROGRAMENDCG 关键字之间,或者 HLSLPROGRAMENDHLSL 之间。后一种形式不会自动包含 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

另请参阅


  • 2019–05–17 页面已修订
  • 在 Unity 2018.1 中添加了着色器 #pragma 指令
支持 DX11/OpenGL Core 曲面细分的表面着色器
顶点和片元着色器示例