Shader入门(二十)编译指令(Compilation Directives)

发表于2018-02-02
评论0 1w浏览

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传递半角向量给光照模型(默认是视图向量)
会在每个顶点计算并归一化半角向量
这样更快,但是并不完全正确。
approxview5.0中被interpolateview取代
dualforward在前向渲染路径中使用双光照贴图

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引