Version: 2021.1
Shader variant collections
计算着色器

Replacing shaders at runtime

In the Built-in Render Pipeline, you can tell a Camera to change the shader that it uses to render certain geometry at runtime. You might do this to achieve a visual effect such as edge detection.

应通过脚本使用函数 Camera.RenderWithShaderCamera.SetReplacementShader 来实现着色器替换。这两个函数均采用 shaderreplacementTag

工作方式如下:摄像机按正常方式渲染场景,对象仍使用自己的材质,但要更改最终使用的实际着色器:

  • 如果 replacementTag 为空,则使用指定的替换着色器来渲染场景中的所有对象。
  • 如果 replacementTag 不为空,则对于将要渲染的每个对象:
    • 查询真实对象的着色器以获取标签值
    • 如果没有该标签,则不渲染对象。
    • 在替换着色器中找到一个子着色器,并且该子着色器的一个给定标签具有找到的值。如果找不到此类子着色器,则不渲染对象。
    • 现在,使用该子着色器来渲染对象。

So if all shaders would have, for example, a “RenderType” tag with values like “Opaque”, “Transparent”, “Background”, “Overlay”, you could write a replacement shader that only renders solid objects by using one subshader with RenderType=Solid tag. The other tag types would not be found in the replacement shader, so the objects would be not rendered. Or you could write several subshaders for different “RenderType” tag values. Incidentally, all built-in Shader objects have a “RenderType” tag set.

光照着色器替换

使用着色器替换时,将使用摄像机上配置的渲染路径来渲染场景。这意味着用于替换的着色器可以包含阴影和光照通道(您可以使用表面着色器进行着色器替换)。这对于渲染特殊效果和场景调试很有用。

Shader replacement tags in built-in shaders

All built-in shaders have a “RenderType” tag set that can be used when rendering with replaced shaders. Tag values are the following:

  • __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” 着色器都将使用第二个替换子着色器,以此类推。如果任何对象的着色器不具有替换着色器中指定键的匹配标签值,则不会渲染这样的对象。

Shader variant collections
计算着色器