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