unity 替换渲染 ( Rendering with Replaced Shaders )
官方文档:file:///C:/Program%20Files/Unity/Editor/Data/Documentation/en/Manual/SL-ShaderReplacement.html
圣典文档:http://www.ceeger.com/Components/SL-ShaderReplacement.html
功能:
先说说它能干什么。
有时候实现一些特效,尤其是一些后处理特效,需要将所有物体的 shader 替换为另一套 shader 进行渲染,然后再进行合成或以某种叠加方式叠加到最后的画面上去。
再复杂一点的话,可能不同的物体替换的shader还不一样。
这个时候,总不能手动为每个对象去替换吧,所以就用到这个方法了,帮我们一次替换所有的shader。
实现方法:
Camera.RenderWithShader 和 Camera.SetReplacementShader
这2个方法的区别:
Camera.RenderWithShader
是只替换当前这次渲染的shader
Camera.SetReplacementShader
是一直就换下去了,直到调用ResetReplacementShader
方法时,才会换回来。外加官网文档有这么2句:
The camera will not send OnPreCull, OnPreRender or OnPostRender to attached scripts. Image filters will not be rendered either.
意思是调RenderWithShader
时,不会激发一些方法To make use of this feature, usually you create a camera and disable it. Then call RenderWithShader on it.
还有就是通常使用RenderWithShader
时,都会新建一个相机出来,并把它disable
了
重点:
这2个方法的参数都是一个 shader,一个 tag,重点就是这个tag不好理解。
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不是空的,那么对于每个物体,将进行以下方式进行渲染:
RenderWithShader(Shader.Find("shaderX"), "")
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.
现在可以应用子着色器来渲染物体。
tag 不为空时不太好理解,关键在于 tag 它是一个键值对,包含 key-value 2部分
假设写一个 shader 叫 MyShader,它有一个 subshader ,里面有个tag是 “MyTag” = “ABC”。
调用 RenderWithShader(Shader.Find("MyShader"), "MyTag")
这个时候,如果 scene 中对象上的 shader 不带 MyTag
标签的话,则不渲染
如果有 tag 的话,比如: "MyTag" = "ABC"
,需要去 MyShader 中去找有没有 tag 为 "MyTag" = "ABC"
的 subshader。
如果有的话,会用这个 subshader 去替换对象的 shader 并进行渲染。
没有的话,这个对象也不渲染
等于是分成了2步:
第1步 先用 tag 的 左半部分(key) “MyTag” 筛选了谁不渲染。
第2步 再用 tag 的 右半部份(value) 去 MyShader 中寻找替换用的 subshader ,没有能替换的也不渲染
一般 tag 可以选用 RenderType
,因为 unity 中的 shader 一般都会有这个 tag。