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

发表于2018-02-02
评论0 1.8k浏览

想免费获取内部独家PPT资料库?观看行业大牛直播?点击加入腾讯游戏学院游戏程序行业精英群

711501594

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在前向渲染路径中使用双光照贴图

原文链接

著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

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

游戏学院公众号二维码
腾讯游戏学院
微信公众号

提供更专业的游戏知识学习平台