原文链接
版权声明:本文为CSDN博主「凯奥斯」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
正文
Shader 中编译指令分为两种,
- 一种是常规的编译指令,也就是顶点片元着色器(Vetex & Fragment Shader)使用的编译指令,
- 另一种就是表面着色器(Surface Shader)使用的编译指令。
二者都使用 #pragma 语句来编写,并且都需要写在 CGPROGRAM 和 ENDCG 之间。
区别在于
- VF 编译指令写在 Pass 里面,
- 而表面着色器编译指令写在 SubShader 里面,表面着色器会自行编译到多通道里去,并且需要使用
#pragma surface …指令来标识这是一个表面着色器。
VF 编译指令:
| 指令 | 作用 |
|---|---|
| #pragma vertex name | 编译 name 函数为 顶点 着色器 |
| #pragma fragment name | 编译 name 函数为 片元 着色器 |
| #pragma geometry name | 编译 name 函数为 DX10 的 几何 着色器 注:会自动开启 #pragma target 4.0 |
| #pragma hull name | 编译 name 函数为 DX10 的 壳 着色器 注:会自动开启 #pragma target 5.0 |
| #pragma domain name | 编译 name 函数为 DX10 的 域 着色器 注:会自动开启 #pragma target 5.0 |
| #pragma target name | 表明编译目标 参考着色器编译目标等级 |
| #pragma only_renderers space_separated_names | 只为 指定的渲染平台 渲染着色器 包括下列值: 注[0] |
| #pragma exclude_renderers space_separated_names | 排除 指定的渲染平台 参数同上 |
| #pragma multi_compile... | 参考Shader入门(二十一)多重变体(Multiple Variants) 或者 Unity 官方文档:多重着色器变体 |
| #pragma enable_d3d11_debug_symbols | 生成 d3d11 的调试信息 可以在 VS2012(或以上)使用图形调试器 调试 shader |
| #pragma hardware_tier_variants renderer_name | 针对所选渲染器的每个 硬件层级 生成每个已编译的 Shader 的多重 Shader 硬件变体 参考Shader山下(二十一)多重变体(Multiple Variants) 或者Unity官方文档:多重着色器变体 |
表面着色器编译指令,只有 #pragma surface 一个,写法:
#pragma surface surfFunc lightingModel [optional params]
但是可以为这条指令配置不同的选项:
1. 必选项
| 名称 | 说明 |
|---|---|
| surfaceFunc | 表面着色器函数 |
| lightingModel | 注[1] |
2. 可选项
| 名称 | 说明 |
|---|---|
| alpha 或者 alpha:auto | 透明度混合 对于简单的光照模型(例如 Lambert 和 BlinnPhong)使用 alpha:fade 对于基于物理的光照模型使用 alpha:premul(具体参考 表面着色器中的自定义光照模型) |
| alpha:blend | 透明度混合 |
| alpha:fade | 传统透明度混合(参考 Shader山下(十八)混合(Blend)命令) |
| alpha:premul | 预乘透明度混合 |
| alphatest:variable_name | 透明度测试,并使用 variable_name 作为裁切阈值 |
| keepalpha | 对于默认的不透明 Shader,会 无视 光照模型返回的透明度值,直接把 1.0 写入 Alpha 通道。 使用 keepalpha 选项,允许在不透明 Shader 里保留光照模型返回的透明度值。 |
| decal:add | 附加的贴花 shader,这意味着对象在其他表面的上面并使用 添加 方法进行混合。 |
| decal:blend | 半透明贴花 shader,这意味着对象在其他表面的上面并使用 透明度方法 进行混合。 |
| vertex:vertex_function | 自定义顶点函数 |
| finalcolor:color_function | 自定义的最终颜色修改函数 |
| finalgbuffer:gbuffer_function | 自定义的改变 GBuffer 内容的延迟路径 |
| finalprepass:prepass_function | 自定义的预通道基础路径 |
| addshadow | 生成一个阴影投射通道: 一般用于自定义顶点函数,这样的话,就可以对阴影投射使用程序化的顶点动画。 一般情况下,shader 并不需要任何特殊的阴影处理,因为它们可以使用 Fallback 里的阴影投射通道 |
| fullforwardshadows | 支持前向渲染路径里的所有光照阴影: 默认情况下 只支持一个平行光 的阴影 如果需要点光源(point)或者聚光灯(spot)的阴影,那么就要使用这个选项 |
| tessellate:tessellate_function | 使用 DX11 的 GPU 细分,tessellate_function 计算细分参数 参考表面着色器细分 |
| exclude_path:path | 不生成指定渲染路径的通道 可选项: deferred forwad prepass |
| noshadow | 禁用阴影 |
| noambient | 禁用环境光或者光探头 |
| novertexlights | 禁用前向渲染中的光探头或者每顶点光照 |
| nolightmap | 禁用所有的光照贴图 |
| nodynlightmap | 禁用动态光照贴图 |
| nodirlightmap | 禁用平行光照贴图 |
| nofog | 禁用内置雾效 |
| nometa | 不生成元通道 光照贴图和动态全局光照使用元通道来提取表面信息 |
| noforwardadd | 禁用前置渲染的附加通道: 这样就让 shader 支持一个完全平行光,而 其他的光 使用每顶点或者 SH(球谐函数)计算 同样让 shader 变得更轻 |
| softvegetation | 在 Quality Setting 里的 Soft Vegetation 被开启的时候,才会被渲染 |
| interpolateview | 在 顶点着色器 中计算 视图方向 并插入它(默认在像素着色器中计算) 这样使得 Shader 变得更快,不过 需要多使用一个纹理插值。 |
| halfasview | 传递 半角向量 给光照模型(默认是视图向量) 会在每个顶点计算并归一化半角向量 这样更快,但是 并不完全正确。 |
| approxview | 5.0 中被 interpolateview 取代 |
| dualforward | 在前向渲染路径中使用双光照贴图 |
注
0
d3d9:Direct3D 9;d3d11:Direct3D 11/12;glcore:OpenGL 3.x/4.x;gles:OpenGL ES 2.0;gles:OpenGL ES 3.x;metal:IOS&Mac Metal;d3d11_9x:Direct3D 11; 9.x 特性等级一般用于 WSA 平台xbox360:Xbox 360;xboxone:Xbox One;ps4:PlayStation 4;psp2:PlayStation Vita;n3ds:Nintendo 3DS;wiiu:Nintendo Wii U
1
光照模型函数
- 内置模型:
Standard - 基于物理 的漫反射模型
StandardSpecular - 基于物理 的高光模型
Lambert - 不基于物理 的漫反射模型
BlinnPhong - 不基于物理 的高光模型 也可以自己写,命名规则:
Lighting...。
...为在编译指令里填写的名称例如:
#pragma surface surf Custom光照模型函数名就要写成:LightingCustom(具体参考表面着色器中的自定义光照模型)