前言

上一篇介绍了ShaderLab的结构,这一篇继续介绍Shader的主要逻辑部分。

Unity的旧版本用的是CG语言,现在逐步淘汰了,主要用微软的HLSL,并加了一些Unity自己的语法。

预处理

include

include and include_with_pragmas directives in HLSL - Unity 手册

在 HLSL 中,#include 指令是一种预处理器指令。它们指示编译器将一个 HLSL 文件的内容包含在另一个 HLSL 文件中。它们包含的文件称为包含文件

#include_with_pragmas 指令的工作方式与常规 #include 指令相同,但它也允许您在包含文件中使用 #pragma 指令。这意味着 #include_with_pragmas 指令允许您在多个文件之间共享 #pragma 指令。

在 HLSL 中向着色器编译器提供信息

Provide information to the shader compiler in HLSL - Unity 手册

#pragma target 3.0
#pragma exclude_renderers vulkan
#pragma vertex vert
#pragma fragment frag

// The rest of your HLSL code goes here

指定着色器阶段

语句功能
#pragma vertex <name>Compile the function with the given name as the vertex shader. Replace with the function name. This directive is required in regular graphics shaders.将具有给定名称的函数编译为顶点着色器。 替换为函数名称。此指令在常规图形着色器中是必需的。
#pragma fragment <name>Compile the function with the given name as the fragment shader. Replace with the function name. This directive is required in regular graphics shaders.将具有给定名称的函数编译为片段着色器。 替换为函数名称。此指令在常规图形着色器中是必需的。
#pragma geometry <name>Compile the function with the given name as the geometry shader. Replace with the function name. This option automatically turns on #pragma require geometry; for more information, see Targeting shader models and GPU features in HLSL.将具有给定名称的函数编译为几何着色器。 替换为函数名称。此选项会自动打开 #pragma 需要几何图形;有关详细信息,请参阅在 HLSL 中面向着色器模型和 GPU 功能Note: Metal does not support geometry shaders.注意:Metal 不支持几何体着色器。
#pragma hull <name>Compile the function with the given name as the DirectX 11 hull shader. Replace with the function name. This automatically adds #pragma require tessellation; for more information, see Targeting shader models and GPU features in HLSL.将具有给定名称的函数编译为 DirectX 11 hull 着色器。 替换为函数名称。这会自动添加 #pragma 需要曲面细分;有关详细信息,请参阅在 HLSL 中面向着色器模型和 GPU 功能
#pragma domain <name>Compile the function with the given name as the DirectX 11 domain shader. Replace with the function name. This option automatically turns on #pragma require tessellation; for more information, see Targeting shader models and GPU features in HLSL.将具有给定名称的函数编译为 DirectX 11 域着色器。 替换为函数名称。此选项会自动打开 #pragma 需要镶嵌;有关详细信息,请参阅在 HLSL 中面向着色器模型和 GPU 功能

着色器变体和关键字

Directive 命令描述
#pragma multi_compile <keywords>Declares a collection of keywords. The compiler includes all of the keywords in the build.声明关键字的集合。编译器在构建中包含所有关键字。You can use suffixes such as _local to set additional options.您可以使用后缀(如 _local)来设置其他选项。For more information and a list of supported suffixes, see Declaring and using shader keywords in HLSL.有关详细信息和支持的后缀列表,请参阅在 HLSL 中声明和使用着色器关键字
#pragma shader_feature <keywords>Declares a collection of keywords. The compiler excludes unused keywords from the build.声明关键字的集合。编译器会从构建中排除未使用的关键字。You can use suffixes such as _local to set additional options.您可以使用后缀(如 _local)来设置其他选项。For more information and a list of supported suffixes, see Declaring and using shader keywords in HLSL.有关详细信息和支持的后缀列表,请参阅在 HLSL 中声明和使用着色器关键字
#pragma hardware_tier_variants <values>Built-in Render Pipeline only: Add keywords for graphics tiers when compiling for a given graphics API. For more information, see Graphics tiers.仅限内置渲染管线:在为给定图形 API 编译时为图形层添加关键字。有关详细信息,请参阅图形层
#pragma skip_variants <list of keywords>Strip specified keywords.去除指定的关键字。

GPU 要求和着色器模型支持

语句功能
#pragma target <value>The minimum shader model that this shader program is compatible with. Replace with a valid value. For a list of valid values, see Shader compilation: Targeting shader models and GPU features in HLSL.此着色器程序兼容的最小着色器模型。 替换为有效值。有关有效值的列表,请参阅着色器编译:面向 HLSL 中的着色器模型和 GPU 功能
#pragma require <value>The minimum GPU features that this shader is compatible with. Replace with a valid value, or multiple valid values separated by a space. For a list of valid values, see Shader compilation: Targeting shader models and GPU features in HLSL.此着色器兼容的最低 GPU 功能。 替换为一个有效值,或用空格分隔的多个有效值。有关有效值的列表,请参阅着色器编译:面向 HLSL 中的着色器模型和 GPU 功能

其他

Shader模型和特性

Targeting shader models and GPU features in HLSL - Unity 手册

Targeting graphics APIs and platforms in HLSL - Unity 手册

变体

Declaring and using shader keywords in HLSL - Unity 手册

Shader变体

着色器变体和关键字 - Unity 手册

Shader变体有两种声明方法。

shader_featuremulti_compile 都是 Unity Shader 中用于控制着色器变体(Shader Variants)生成的关键字,但它们有一些区别:

  1. shader_feature
    
    • 仅在使用到相关特性时才会编译包含该特性的变体。
    • 可以减少最终生成的变体数量,因为只有实际需要的变体才会被编译。
    • 适用于那些在运行时根据某些条件才启用的特性,例如某些高级图形效果可能只在特定设备或场景中使用。
  2. multi_compile
    
    • 会编译所有指定的变体,无论是否实际使用到。
    • 会导致生成更多的变体,可能会增加编译时间和占用更多的内存。
    • 适用于那些需要在不同情况下切换使用的多个变体,例如不同的光照条件或材质属性。
  3. dynamic_branch
    
    • 无变体
    • 增加GPU压力

在代码端,需要配合API动态修改本地的关键字或者全局的关键字,参考以下

Using shader keywords with C# scripts - Unity 手册

总结

Shader中的HLSL部分总结就这么多,需要更详细的说明可以参考Unity官方教程。