Notifications
Article
零基础入门Unity Shader(九)
Published 8 months ago
1.1 K
8
零基础入门Unity Shader(九)

前言

在前面的章节中我们有讨论过每个Shader中都可以有多个SubShader,并且在渲染时会找到第一个合适的并执行。那么除了在SubShader中定义的Pass 不同以外,我们还能如何定义SubShader呢,我们知道在SubShader和Pass中都有Tags可选参数组,Tags的作用是告诉引擎如何去渲染我们的对象,语法格式如下:
Tags { "TagName1" = "Value1" "TagName2" = "Value2" }
通过Tags{}来表示我们添加了一系列的参数标识,大括号内可以添加多组Tag(所以才叫Tags嘛),名称(TagName)和值(Value)是成对成对出现的,并且全部用字符串表示。

SubShader Tags

SubShader中的Tags必须放置于SubShader中的Tags内,具体参数有以下这些:
Queue
渲染队列,指定对象什么时候渲染,每个队列其实都是利用一个整数进行索引的。
有以下取值:
  • Background
值为1000,此队列的对象最先进行渲染。
  • Geometry
Queue的默认值,值为2000,通常用于不透明对象,比如场景中的物件与角色等。
  • AlphaTest
值为2450,要么完全透明要么完全不透明,多用于利用贴图来实现边缘透明的效果,也就是美术常说的透贴。
  • Transparent
值为3000,常用于半透明对象,渲染时从后往前进行渲染,建议需要混合的对象放入此队列。
  • Overlay
值为4000,此渲染队列用于叠加效果。最后渲染的东西应该放在这里(例如镜头光晕等)。
写法示例:
Tags{ "Queue" = "Geometry" }
那是不是只有以上这些固定化的渲染队列了呢?
当然不是,我们还有一种方式可以自定义渲染队列:
Tags{ "Queue" = "Geometry+1" }
如上所示,可以通过在值后加数字的形式来进行重新指定渲染队列。
渲染队列直接影响性能中的重复绘制,合理的队列可极大的提升渲染效率。在Unity中,渲染队列小于2500的对象都被认为是不透明的物体,(如“Background”,“Geometry”,“AlphaTest”),这些物体是从前往后绘制的,而使用其他的队列(如“Transparent”,“Overlay”)的物体则是从后往前绘制的。这意味着,我们需要尽可能地把物体的队列设置为不透明物体的渲染队列,而尽量避免重复绘制。

RenderType

自带的值有以下这些:
  • Opaque
  • Transparent
  • TransparentCutout
  • Background
  • Overlay
  • TreeOpaque
  • TreeTransparentCutout
  • TreeBillboard
  • Grass
  • GrassBillboard
这些名称实际上只是一种内部的约定,用来区别这个Shader要渲染的对象是属于什么类别的,你可以想像成是我们把各种不同的物体进行分类一样。当然你也可以改成自定义的名称,这样并不会影响到Shader的效果。
那既然没有什么效果影响,那RenderType又有什么作用呢?
它的作用是可以利用Camera.SetReplacementShader来更改最终的渲染效果。先说下这条语句的语法:
camera.SetReplacementShader (EffectShader, Tag);
这是Unity的脚本API,需要在C#脚本中进行调用。
其中EffectShader是我们需要渲染的Shader,Tag是用来筛选渲染对象用的。
具体按以下规则执行:
  1. 使用SetReplacementShader("shaderA",""),这里Tag为空,表示全部物体Shader都替换成shaderA进行渲染。
  2. SetReplacementShader("shaderA","RenderType"),由于这里Tag为"RenderType",所以先查看场景中的shader中是否有RenderType参数,如果有,再看RenderType中的值是否与shaderA中的RenderType值相等,相等则使用shaderA渲染,否则就不渲染(Game视图什么也没有)。
  3. 关于Tag参数并不局限于RenderType,我们同样可以使用SetReplacementShader("shaderA","IgnoreProjector")或是其他任何参数如:SetReplacementShader("shaderA","ABC")等。
用法示例:
我们建个脚本,添加如下代码,实现替换材质开关功能。
其中taecg/Overdraw(此Shader实现的是类似于Overdraw的效果)这个Shader中的Tag如下:
而我们的物体(这头狼),我们给它的Shader中Tag如下:
然后,我们同时在场景中添加几个其它的默认几何体(它们都是默认的StandardShader)。
结果如下:
首先在场景中查找所有的对象,筛选出有RenderType标签的对象,此时三个物体都有,然后进一步和taecg/Overdraw这个Shader进行对比,发现只有狼的值与此相同,所以只渲染狼,并且是以taecg/Overdraw这个Shader来进行渲染。

DisableBatching tag

有的时候,我们会利用Shader在模型的顶点本地坐标下做一些位移动画,当此模型有批处理时会出现效果不正确的情况,这是因为批处理会将所有几何转换为世界坐标空间,因此“本地坐标空间”将丢失。
"DisableBatching" = "True"
这时我们就可以利用此Tag在Shader中指定是否受批处理影响,有以下3个值可选:
  • False(默认值),不禁用批处理
  • True,始终禁用此着色器的批处理

  • LODFading,仅当LOD激活时禁用批处理

ForceNoShadowCasting tag

是否强制关闭投射阴影,值可为:
  • True,强制关闭投射阴影
  • False(默认值),不关闭投射阴影
"ForceNoShadowCasting" = "True"

IgnoreProjector tag

是否忽略Projector投影器的影响,Projector是Unity中内置的组件,可用于实现贴花等功能。
  • True,使对象不受Projector影响
  • False(默认值),使对象受Projector影响

CanUseSpriteAtlas tag

是否可用于精灵打包图集,意思就是如果某个图片精灵被设置为打包进图集中,那么当此精灵所指定Shader中设置为
"CanUseSpriteAtlas"="False"
时就会使其无法工作,相应的UI上也会有警告提示。

PreviewType tag

此Tag决定了材质面板的预览窗口如何显示模型,默认显示的是球体,当我们把值定义为以下两种情况时会进行相应的变化。此功能仅仅影响的只是材质面板的预览,对Shader本身没有什么影响。
  • Plane
  • 平面预览
  • Skybox
  • 天空盒预览

最后

欢迎大家关注更多干货的公众号:Unity技术美术 ( ID:gh_8b69cca044dc )
Tags:
taecg
TA - Artist
21
Comments
泉壤
2 months ago
试试这个float factor = Mathf.Pow(2,intensity); Color color = new Color(redfactor,greenfactor,blee*factor);
0
菜狗
7 months ago
一只渴望富婆的菜狗
0
菜狗
7 months ago
一只渴望富婆的菜狗
大佬,受我一拜
0
漩涡鸣人
8 months ago
大佬威武 好想和你做网友
0
Yunluo
8 months ago
我怕是负基础
2