前言
上一篇介绍了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变体
Shader变体有两种声明方法。
shader_feature 和 multi_compile 都是 Unity Shader 中用于控制着色器变体(Shader Variants)生成的关键字,但它们有一些区别:
shader_feature- 仅在使用到相关特性时才会编译包含该特性的变体。
- 可以减少最终生成的变体数量,因为只有实际需要的变体才会被编译。
- 适用于那些在运行时根据某些条件才启用的特性,例如某些高级图形效果可能只在特定设备或场景中使用。
multi_compile- 会编译所有指定的变体,无论是否实际使用到。
- 会导致生成更多的变体,可能会增加编译时间和占用更多的内存。
- 适用于那些需要在不同情况下切换使用的多个变体,例如不同的光照条件或材质属性。
dynamic_branch- 无变体
- 增加GPU压力
在代码端,需要配合API动态修改本地的关键字或者全局的关键字,参考以下
Using shader keywords with C# scripts - Unity 手册
总结
Shader中的HLSL部分总结就这么多,需要更详细的说明可以参考Unity官方教程。