目录:Unity Shader - 知识点目录(先占位,后续持续更新)
原文:Writing vertex and fragment shader
版本:2019.1
Writing vertex and fragment shader
编写顶点和片段着色器
ShaderLab编写的着色器包含了不单只是硬件相关的着色器代码。它们处理的内容很多。可以添加材质的Inspector中properties的显示,也包含了多个不同硬件需求的着色器,或是配置固定函数着色器的硬件状态,等等。反正就是可编程着色器,如:顶点和片段着色器程序,它们仅仅是ShaderLab着色器概念中的一部分。可以查看shader tutorial(shader 教程)来了解基础介绍。这里我们将调用低级硬件着色器程序。
如果你想编写一些可以与光照有交互的着色器,可以查看Surface Shaders文档。有一些VS/FS着色器例子,可以查看Vertex and Fragment Shader Examples。
着色器程序适应HLSL语言格式来编写,它们嵌入在Pass块里头。通常是这样的:
Pass {
// ... 这里通常设置一些pass的状态值...
CGPROGRAM
// 这里放一些编译指令,如下:
#pragma vertex vert
#pragma fragment frag
// 这里放Cg/HLSL的代码
ENDCG
}
HLSL代码
HLSL程序代码都写在CGPROGRAM和ENDCG关键字之间,或是HLSLPROGRAM和ENDHLSL之间。后者方式不会自动include HLSL的一些宏定义支持,或是UnityShaderVariables(Unity内置的一些变量)等之类的内置头文件(built-in header files)。
在代码段前面的内容是编译指令,使用**#pragma** 语句。该指令代表这一些编译功能:
- #pragma vertex name - 指定name函数作为vertex shader(顶点着色器)。
- #pragma fragment name - 指定name函数作为fragment shader(片段着色器)。
- #pragma geometry name - 指定name函数作为DX10的geometry shader(几何着色器)。使用该编译选项的将自动添加 #pragma target 4.0 的编译指令选项,下面可以看到该指令的描述。
- #pragma hull name - 指定name函数作为DX11 hull shader(外壳着色器)。使用该编译选项的将自动添加 #pragma target 5.0 的编译指令选项,下面可以看到该指令的描述。
- #pragma domain name - 指定name函数作为DX11 domian shader(域着色器)。使用该编译选项的将自动添加 #pragma target 5.0 的编译指令选项,下面可以看到该指令的描述。
其他编译指令:
- #pragma target name - 指定着色器运行的硬件支持目标版本。查阅Shader Compilation Targets了解更多。
- #pragma require feature … - 提供更细的控制shader需要的功能特性,查阅Shader Compilation Targets了解更多。
- #pragma only_renderers names,name之间以空格隔开 - 仅为目标平台的渲染器编译。默认是对所有的渲染器。查看下面的Renderers了解更多。
- #pragma exclude_renderers names,name之间以空格隔开。默认是对所有的渲染器。查看下面的Renderers了解更多。
- #pragma multi_compile … 为multiple shader variants(着色器变体)而设置。未使用的multi_compile变体着色器也会包含在游戏构建后。
- #pragma multi_compile_local … 与multi_compile类似。查阅Making multiple shader proogram variants: Keyword limits(多着色器变体:关键字限制)了解更多信息。
- #pragma shader_feature … 为multiple shader variants(着色器变体)而设置。未使用的shader_feature变体着色器不会包含在游戏构建后。
- #pragma shader_feature_local … 与shader_feature类似。查阅Making multiple shader program variants: Keyword limits了解更过信息。
- pragma enable_d3d11_debug_symbols - 为DirectX11 生成着色器编译的调试信息,这将允许你通过Visual Studio 2012(或更高版本) Graphics debugger来调试着色器。
- #pragma hardware_tier_variants renderer name - 给每个编译了的着色器生成multiple shader hardward variants,为每个选中的渲染器设置对应能运行的硬件层。查阅下面Renderers了解更多。
- #pragma hlslcc_bytecode_disassembly - 将反编译的HLSLcc bytecode嵌入着色器。
- pragma disable_fastmath - 启用严格的IEEE 754规则,涉及多数NaN的处理(当前仅对Metal平台有效)。
- pragma glsl_es2 - 当在GLSL类型的着色器上设置了,将生成GLSL ES 1.0(OpenGL ES 2.0)着色器,就算着色器的目标版本为OpenGL ES 3。
- #pragma editor_sync_compilation - 强制同步编译的方式(仅对Unity Editor有效果)。
每个着色器代码至少都会有一个顶点程序和一个片段程序。因为 #pragma vertex 和 #pragma fragment 指令都是必要的。
从Unity 5.0 开始,部分编译指令不处理任何东西,所以可以安全的删除:#pragma glsl,#pragma glsl_no_auto_normalization,#pragma profileoption,#pragma fragmentoption。
Unity仅支持 #pragma 指定在shader文件中,不能放在include之类的头文件。
Rendering platforms
渲染平台
Unity支持一些rendering(渲染) APIs(如:Direct3D 11和OpenGL),且默认的所有着色器程序都编译到了支持的渲染器中。你可以使用 #pragma only_renderers 或是 #pragma exclude_renderers 指令来表示想要编译的目标渲染器。这对应明确知道一个着色器语言的特性不不可能在某些平台上运行情况下是很有用的。支持的渲染器名称有:
- 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
See Also
参见