Unity3d Shader开发(四)UsePass ,GrabPass ,SubShader Tags

时间:2024-11-29 09:05:43

(一)UsePass 命令 使用 来自另一个着色器的命名通道。

Syntax 语法

UsePass "Shader/Name"
插入所有来自给定着色器中的给定名字的通道。Shader/Name包含了通过斜杠字符分割的着色器的名字和通道的名字
某些着色器重用其他着色器中已存在的通道,减少重复的代码。例如,在许多像素光照着色器中,阴影色或顶点光照通道在在相应的顶点光照着色器中是相同的。UsePass命令只是包含了另一个着色器的给定通道。例如当如下的命令可以使用内置的高光着色器中的名叫"Base"的通道:
UsePass "Specular/BASE"
为了让UsePass能正常工作,必须给希望使用的通道命名。通道中的Name命令将提供这个名字:
Name "MyPassName"
注意,所有通道名字都是大写开头,因此UsePass必须使用大写开头的名字来书写索引 。

(二)GrabPass 是一种特殊的通道类型 - 捕获物体所在位置的屏幕的内容并写入到一个纹理中。这个纹理能被用于后续的通道中完成一些高级图像特效。

Syntax 语法

有两种方式将GrabPass放入一个 subshader 中:

  • GrabPass {} 能捕获当前屏幕的内容到一个纹理中。纹理能在后续通道中通过 _GrabTexture 进行访问。注意:这种形式的捕获通道将在每一个使用该通道的对象渲染过程中执行昂贵的屏幕捕获操作
  • GrabPass { "TextureName" } 能捕获屏幕内容到一个纹理中,但只会在每帧中处理第一个使用给定纹理名的纹理的对象的渲染过程中产生捕获操作。纹理在未来的通道中可以通过给定的纹理名访问。当你在一个场景中拥有多个使用GrabPass的对象时将提高性能。

此外,GrabPass能使用Name 和 Tags命令。

这里有一种反相已被渲染的像素的颜色的昂贵方式:

Shader "GrabPassInvert" {
SubShader {
// Draw ourselves after all opaque geometry
// 在所有不透明几何体之后自画
Tags { "Queue" = "Transparent" } // Grab the screen behind the object into _GrabTexture
// 捕获对象后的屏幕到_GrabTexture
GrabPass { } // Render the object with the texture generated above, and invert it's colors
// 用前面捕获的纹理渲染对象,并反相它的颜色
Pass {
SetTexture [_GrabTexture] { combine one-texture }
}
}
}

这个着色器有两个通道:第一个通道捕获在渲染时刻对象背后的所有图像,然后执行第二次通道。当然,在现在,实现同样的效果,使用反相 混合模式将更加廉价。


(三)Tags 子着色器使用标签来告诉渲染引擎期望何时和如何渲染对象。

Syntax 语法

Tags { "TagName1" = "Value1" "TagName2" = "Value2}
为标签 指定 值。能设定任意多标签
标签是标准的键值对。在其中有一个SubShader 标签被用于决定渲染的次序和子着色器中的其他标签。

Rendering Order - Queue tag
渲染次序 - 队列 标签

你能使用 Queue 标签决定对象被渲染的次序。着色器决定它所归属的对象的渲染队列,任何透明渲染器可以通过这个办法确认可以在所有不透明对象渲染后再进行渲染。

有四种预定义的渲染队列,在预定义队列之间还可以定义更多队列

    • Background
      后台 - 这个渲染队列在所有队列之前被渲染,被用于渲染天空盒之类的对象。
    • Geometry (default) - 
      几何体(缺省) - 这个队列被用于大多数对象。 不透明的几何体使用这个队列。
    • Transparent -
      透明 - 这个渲染队列在几何体队列之后被渲染,采用由后到前的次序。任何采用alpha混合的对象(不对深度缓冲产生写操作的着色器)应该在这里渲染(玻璃,粒子效果)
    • Overlay
      覆盖 - 这个渲染队列被用于实现叠加效果。任何需要最后渲染的对象应该放置在此处。(如镜头光晕)
Shader "Transparent Queue Example" {
SubShader {
Tags {"Queue" = "Transparent" }
Pass {
// rest of the shader body...
}
}
}

举例说明如何在透明队列中渲染对象。

几何体渲染队列为了达到最优的性能优化了对象的绘制次序。其他渲染队列依据举例排序对象,从最远的对象开始渲染到最近的对象。

对于特殊的需要可以使用中间队列来满足。在Unity实现中每一个队列都被一个整数的索引值所代表。后台为1000,几何体为2000,透明为3000,叠加层为4000. 着色器可以自定义一个队列

Tags { "Queue" = "Geometry+1" }

这会使对象在所有不透明的对象渲染之后但却在所有透明物体前被渲染,该渲染队列的索引值为2001.当你希望某些对象总是在其他某些对象前被绘制的情况下,这种能力对你有用。例如,在大多数时候,透明的水总是应该在所有不透明的物体之后并在透明对象前被渲染。

IgnoreProjector tag 忽略投影 标签

如果设置忽略投影标签为"True",那么使用这个着色器的对象将不会被投影机所影响。对半透明的物体来说最有用处,因为没有对他们产生投影的好办法。