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
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.