x作用:

在渲染时,通过SetReplacementShader控制实时生效的shader,可以在运行时修改部分or全部object的shader来实现特定的效果。


函数说明:

Camera.SetReplacementShader
public void SetReplacementShader(Shader shader, string replacementTag);
Description
Make the camera render with shader replacement.
See Rendering with Replaced Shaders page for details.
After calling this function, camera will render its view with shader replacement. Call ResetReplacementShader to reset it back to normal rendering.
See Also: Rendering with Replaced Shaders, ResetReplacementShader, RenderWithShader.
参数:
shader 替换使用的shader
replacementTag 替换标识
替换标识(replacementTag),这里比较难理解,官方文档的说明也比较简略。
具体的说有以下几种情况:
1. replacementTag == "" ,将所有object以替换的shader(即第一个参数传入的shader)渲染
2. replacementTag ~= ""
          2-1.替换的shader没有replacementTag or 没有找到,则不渲染
          2-2.替换的shader有replacementTag,则使用替换的shader渲染

运行结果:

Replace with Green:

unity ProjectBrowser unity projectbrowser.repaint_Replaced Shaders

Replace_NoRenderType:

unity ProjectBrowser unity projectbrowser.repaint_着色器_02

Replace with Nothing:

unity ProjectBrowser unity projectbrowser.repaint_sed_03

Replace with 2 subshaders:

查找MyTag并替换为蓝色

unity ProjectBrowser unity projectbrowser.repaint_着色器_04

unity ProjectBrowser unity projectbrowser.repaint_sed_05

调整上面EffectShader中的两个subshader的顺序后,出现了不一样的情况:

unity ProjectBrowser unity projectbrowser.repaint_sed_06

unity ProjectBrowser unity projectbrowser.repaint_Replaced Shaders_07

第一个蓝色的cube变成了青色!这是什么原因呢?推测应该是替换shader的顺序导致的。

替换shader的顺序

for (object shader的RenderType)

{
    for (replace shader的RenderType)

    {
        if (Find == true)

        {
            // 替换shader

            break;
        }

    }
}

交换EffectShader中subshader的顺序,左边蓝色的cube颜色会变成青色

查找的顺序是遍历object的shader下所有subshader的RenderType,嵌套遍历replaceshader下所有subshader的RenderType,如果找到了,跳出循环,替换shader.


参考资料:

Rendering with Replaced Shaders


shader通过camera中 Camera.RenderWithShader 和 Camera.SetReplacementShader实现替换功能,这两个方法都接受两个参数:Shader和replacementTag ,根据情况:

* replacementTag 为空,场景中所有物体都会使用replacement shader进行渲染

* replacementTag 不为空,如果物体不存在tag则不进行渲染。

* replacementTag 不为空,如果物体shgader中存在、与之placement shader中相同的tag',则使用placement shader中对应subshader进行渲染,否则不渲染。



It works like this: the camera renders the scene as it normally would. the objects still use their materials, but the actual shader that ends up being used is changed:

它是像这样来进行工作的:相机还是像平常一样来渲染场景,物体也还是使用原有的材质,但是他们的真实材质是在使用时来进行改变:

* If replacementTag is empty, then all objects in the scene are rendered with the given replacement shader.

如果replacementTag是空的,那么场景中的所有物体都用给定的替换着色器来进行渲染。

* If replacementTag is not empty, then for each object that would be rendered:

如果replacementTag不是空的,那么对于每个物体,将进行以下方式进行渲染:

    * The real object's shader is queried for the tag value.

按照标签值来查找物体真正的着色器。

    * If it does not have that tag, object is not rendered.

如果没有标签,物体将不进行渲染。

    * A subshader is found in the replacement shader that has a given tag with the found value. If no such subshader is found, object is not rendered.

在替换着色器中,我们可以根据一个具有查找值的标签来找到一个子着色器,如果没有这样的子着色器,该物体将不进行渲染。

    * Now that subshader is used to render the object.

现在可以应用子着色器来渲染物体。

http://www.ceeger.com/Components/SL-ShaderReplacement.html