着色编程规范:渲染方案
每一个在unity内创建的着色器文件【shader】都有非常多的渲染方案【subshaders】。当我们要对某个游戏物体进行渲染时,图形设备会自动选取最适应自身的着色器,然后使用该着色器的第一个渲染方式进行渲染。(图形工程师会根据渲染方式的频率从高到低地排序编码,最常用的放在最前面)。
语法结构
- Subshader { [Tags] [CommonState] Passdef [Passdef ...] }
复制代码
使用上述语法可在渲染方案块【subshaders】内定义可选的标签,状态和通道。
详情
一种渲染方案【subshaders】必定有多个渲染通道【Pass】。我们可以根据需求在这些通道内开启或者关闭某种状态(如启用光照)。另外,我们还可以设定渲染方案的标签。
当GPU开始调用/加载某段着色器代码时, 意味着它正使用着自己定义的渲染通道对游戏物体进行渲染。考虑到实时渲染会占用很多GPU资源,所以在编写着色器程序时,尽量不要给某个渲染方案分配过多的渲染通道。当然,有些渲染效果会占用多个渲染通道,此时允许使用多通道渲染。
渲染通道分为【regular Pass】,【Use Pass】和【Grab Pass】。
可以将某些重用频率高的状态单独编写在某种渲染方案的Subshader块中,这样将可供其他渲染通道/渲染方案使用这个“共享”状态。
Example
- // ...
- SubShader {
- Pass {
- Lighting Off
- SetTexture [_MainTex] {}
- }
- }
- // ...
复制代码
上述渲染方案(subshader)只定义了一个渲染通道。该通道不使用光影效果,并且只使用【_MainTex】进行渲染。
着色编程规范: UsePass命令
使用该命令可调用其它着色器文件的渲染通道。
语法结构
详情
为了减少重复代码量,我们推荐您引用别的着色器文件的渲染通道以达到代码复用的目的。比如,存在一个着色器通道用于渲染游戏物体的轮廓,当你想在别的着色器文件使用这个通道时,可使用上述命令。下面例子就是描述【VertexLit shader】着色器文件引用名为【VertexLit shader】下的【SHADOWCASTER】的渲染通道。
为了保证UsePass命令能正常运行,我们需要给第一个渲染通道进行命名。可在该通道内使用【Name】命令命名通道。
需要注意的是,通道命名区分大小写。
着色编程规范: GrabPass命令
GrabPass 是一种特殊的通道类型 – 获取物体将要绘制到屏幕的相关位置信息,并保存到一个纹理中。这个纹理所存储的信息将被用于后续的通道,完成一些高级图像特效渲染。
语法结构
在渲染方案中【GrabPass】有两种调用方式:
直接使用【GrabPass { }】标签获取物体将要绘制到屏幕上的位置,并保存在某个纹理图上,在其他渲染通道中可通过使用_GrabTexture进行访问。值得注意的是,由于该纹理可共享,所以GPU开销大。
【GrabPass { "TextureName" }】也会获取物体将要绘制到屏幕上的位置,并保存在某个纹理图上。但该命令只会在每一帧获取第一个使用给定纹理名的游戏物体。在下一个渲染通道内可通过给定的纹理名进行访问。当你要获取多个物体的渲染通道时,推荐使用这种最简便的方法。
另外,该通道命令也可以命名和使用标签。
Example
下列范例适用于高性能显卡,用于获取已渲染物体的反相颜色。
- Shader "GrabPassInvert"
- {
- SubShader
- {
- // Draw ourselves after all opaque geometry
- Tags { "Queue" = "Transparent" }
-
- // Grab the screen behind the object into _GrabTexture
- GrabPass { }
-
- // Render the object with the texture generated above, and invert the colors
- Pass
- {
- SetTexture [_GrabTexture] { combine one-texture }
- }
- }
- }
复制代码
这个着色器有两个渲染通道:第一个通道实时获取渲染时游戏物体将要绘制的位置,然后应用于第二次通道。当然,在现在,可使用反相 混合模式实现同样的效果,这种操作更加节约性能。
更多详情
Regular Pass command常规通道命令
着色编程规范:渲染方案/子着色器标签通过使用着色器标签可指定渲染引擎如何以及何时渲染游戏物体。
语法结构
- Tags { "TagName1" = "Value1" "TagName2" = "Value2" }
复制代码
可以按照实际需求定义标签,然后一一对应赋值。
详情
根据语法结构可知,标签内容都是键值对(一一对应)。通道标签在渲染方案里用于决定渲染次序和其他渲染方案的参数。注意,以下的标签只能在渲染通道外【Pass】渲染方案【SubShader】内进行标注。
除了使用内置的渲染标签,您还可以通过使用这个方法【Material.GetTag】调用自定义标签。
渲染队列标签--- Queue
当使用这个标签时,您可以决定游戏物体在何处进行渲染。使用该标签可确定渲染队列的归属,并且保证透明物体在不透明物体后面渲染等。
下列有四种预定义渲染队列,但可在渲染队列中插入更多的队列。
Background-- 最后渲染队列,大多数用于背景渲染。
Geometry(默认队列)-- 通常用于渲染大多数不透明的图形队列。
AlphaTest – 透明通道渲染队列,通常将其与图形通道分开,先渲染RGB部分,然后再接着渲染透明,这样的效率非常高。
Transparent –居于队列中间,在图形和透明通道队列渲染完成后才调用。任何透明混合操作都属于进行Transparent渲染。
Overlay—这个队列用于覆盖效果。覆盖在其他物体之上时使用(如如镜头耀斑)。
- Shader "Transparent Queue Example"
- {
- SubShader
- {
- Tags { "Queue" = "Transparent" }
- Pass
- {
- // rest of the shader body...
- }
- }
- }
复制代码
该范例用于渲染透明队列中的物体。
如果项目有特殊渲染要求,可队列之间进行嵌入。GPU进行着色时会按照渲染队列数值进行渲染。Background,Geometry,AlphaTest,Transparent,Overlay的整型数值为1000,2000,2450,3000,4000.如果使用下列命令进行嵌入:
- Tags { "Queue" = "Geometry+1" }
复制代码
此时该物体(2001)的渲染时机会先于transparent但后于opaque/ Geometry。这可将某种渲染嵌入队列之间。如水纹渲染就位于Geometry和transparent之间。
自定义一个位于2500的序列,在此时渲染不透明的游戏物体可获得最好性能。对透明物体的距离(次序)进行排序,然后按照次序高低进行渲染,推荐透明物体渲染队列在2500之上。而天空盒的渲染一般位于2000和3000之间。
渲染类型标签
该标签会对着色器进行分类。如某某是不透明着色器,某某用于阿尔法测试等等。通常在【ShaderReplacement】内使用,有时也用于生成摄像机深度纹理。
【关闭批量顶点转换】标签
当批量处理物体顶点的空间转换时,相应的着色器并不起作用,因为此时的物理空间没有参照物。
上述标签用于此种情况,其值有三:1.True,关闭批量处理功能;2.true,开启批量处理功能;3.背面消隐:背面消隐时关闭批量处理功能,一般用于树木。
关闭阴影【ForceNoShadowCasting】标签
如果在渲染方案内使用该标签,并设置其值为“true”时,那么使用了这个着色器片段的游戏物体将不会渲染其阴影。当您不想引用别的渲染方案的阴影通道时,使用该标签能极大节约性能。
关闭透视【IgnoreProjector】标签
如果在渲染方案内使用该标签,并设置其值为“true”时,那么使用了这个着色器片段的游戏物体将不会受到近大远小的透视投影效果。推荐在半透明物体上使用,因为这些物体是否具有透视效果都不影响游戏体验。
启用图集【CanUseSpriteAtlas】标签
如果该着色器片段仅用于处理图片时,并且设置【CanUseSpriteAtlas】的值为False,当想把图片打包成图集时,这个命令不会其作用。
预览类型【PreviewType】标签
一般情况下,点击某个材质可在材质属性面板上预览到材质。默认材质都是球型的,使用该标签可将预览模型改为“2D平面”或者“3D天空盒”。 |
|
|
|
|
|