Unity-使用替换的着色器进行渲染
有些渲染效果需要使用一组不同的着色器来渲染场景。例如,良好的边缘检测要求纹理具有场景法线,这样才能检测出表面方向不同的边缘。其他效果可能要求纹理具有场景深度,诸如此类。为此,可使用所有对象的替换着色器来渲染场景。
应通过脚本使用函数 Camera.RenderWithShader 或 Camera.SetReplacementShader 来实现着色器替换。这两个函数均采用 shader 和 replacementTag。
工作方式如下:摄像机按正常方式渲染场景,对象仍使用自己的材质,但要更改最终使用的实际着色器:
如果 replacementTag 为空,则使用指定的替换着色器来渲染场景中的所有对象。
如果 replacementTag 不为空,则对于将要渲染的每个对象:
查询真实对象的着色器以获取标签值。
如果没有该标签,则不渲染对象。
在替换着色器中找到一个子着色器,并且该子着色器的一个给定标签具有找到的值。如果找不到此类子着色器,则不渲染对象。
现在,使用该子着色器来渲染对象。
因此,比如说,如果所有着色器都要有一个值为“Opaque”、“Transparent”、“Background”或“Overlay”的“RenderType”标签,则可编写一个替换着色器,该着色器只使用一个具有 RenderType = Solid 标签的子着色器来渲染实体对象。在替换着色器中找不到其他标签类型,因此不会渲染对象。或者您也可以为不同“RenderType”标签值编写若干子着色器。顺便提一下,Unity 的所有内置着色器都设置了一个“RenderType”标签。
光照着色器替换
使用着色器替换时,将使用摄像机上配置的渲染路径来渲染场景。这意味着用于替换的着色器可以包含阴影和光照通道(您可以使用表面着色器进行着色器替换)。这对于渲染特殊效果和场景调试很有用。
Unity 内置着色器中的着色器替换标签
Unity 的所有内置着色器都设置了一个“RenderType”标签,可以在使用替换着色器进行渲染时使用此标签。标签值如下:
__Opaque__:大部分着色器(法线、自发光、反射和地形着色器)。
__Transparent__:大部分半透明着色器(透明、粒子、字体和地形附加通道着色器)。
__TransparentCutout__:遮罩透明度着色器(透明镂空、两个通道植被着色器)。
__Background__:天空盒着色器。
__Overlay__:光环、光晕着色器。
__TreeOpaque__:地形引擎树皮。
__TreeTransparentCutout__:地形引擎树叶。
__TreeBillboard__:地形引擎公告牌树。
__Grass__:地形引擎草。
__GrassBillboard__:地形引擎公告牌草。
内置场景深度/法线纹理
摄像机内置了渲染深度或深度+法线纹理的功能(可能在某些效果中需要该功能)。请参阅摄像机深度纹理页面。请注意,在某些情况下(取决于硬件),可以使用着色器替换方法在内部渲染深度和深度+法线纹理。因此,务必在着色器中设置正确的“RenderType”标签。
代码示例
Start() 函数指定替换着色器:
此函数请求 EffectShader 使用 RenderType 键。对于所需的每个 RenderType,EffectShader 都有一个键/值标签。Shader 应如下所示:
SetReplacementShader 将检查场景中的所有对象,不使用它们的普通着色器,而是使用第一个具有指定键的匹配值的子着色器。在此示例中,任何对象的着色器若具有 Rendertype=“Opaque” 标签,都将被 EffectShader 中的第一个子着色器替换,任何对象若具有 RenderType=“SomethingElse” 着色器都将使用第二个替换子着色器,以此类推。如果任何对象的着色器不具有替换着色器中指定键的匹配标签值,则不会渲染这样的对象。