Shader入门(二十)编译指令(Compilation Directives)
发表于2018-02-02
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 | 只为指定的渲染平台渲染着色器 包括下列值: 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 |
#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]
但是可以为这条指令配置不同的选项:
surfaceFunction(必选) | 表面着色器函数 |
lightModel(必选) | 光照模型函数,内置模型: Standard:基于物理的漫反射模型 StandardSpecular:基于物理的高光模型 Lambert:不基于物理的漫反射模型 BlinnPhong:不基于物理的高光模型 也可以自己写,命名规则:Lighting... ...为在编译指令里填写的名称 例如#pragma surface surf Custom 光照模型函数名就要写成: LightingCustom 具体参考表面着色器中的自定义光照模型 |
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 | 在前向渲染路径中使用双光照贴图 |