【转载】Shader 山下(二十)编译指令(Compilation Directives)

297 阅读5分钟

原文链接

版权声明:本文为CSDN博主「凯奥斯」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:blog.csdn.net/ecidevilin/…

正文

Shader 中编译指令分为两种,

  • 一种是常规的编译指令,也就是顶点片元着色器(Vetex & Fragment Shader)使用的编译指令,
  • 另一种就是表面着色器(Surface Shader)使用的编译指令。

二者都使用 #pragma 语句来编写,并且都需要写在 CGPROGRAMENDCG 之间。

区别在于

  • 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透明度混合 对于简单的光照模型(例如 LambertBlinnPhong)使用 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 变得更轻
softvegetationQuality Setting 里的 Soft Vegetation 被开启的时候,才会被渲染
interpolateview顶点着色器 中计算 视图方向 并插入它(默认在像素着色器中计算) 这样使得 Shader 变得更快,不过 需要多使用一个纹理插值。
halfasview传递 半角向量 给光照模型(默认是视图向量) 会在每个顶点计算并归一化半角向量 这样更快,但是 并不完全正确
approxview5.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 (具体参考表面着色器中的自定义光照模型