unity, 替換shader渲染(Rendering with Replaced Shaders)【轉】

       實現特效,尤爲是一些後處理特效,常常須要將各物體的shader替換爲另外一套shader進行渲染到紋理,再後再進行合成或以某種疊加方式疊加到最後的畫面上去。html

再複雜一點兒的,可能不一樣的物體所用的替換shader還不同。ide

unity中Camera.RenderWithShader可實現這個功能。函數

下面是官方文檔原話:ui

Rendering with Replaced Shaders

Some rendering effects require rendering a scene with a different set of shaders. For example, good edge detection would need a texture with scene normals, so it could detect edges where surface orientations differ. Other effects might need a texture with scene depth, and so on. To achieve this, it is possible to render the scene with replaced shaders of all objects.this

Shader replacement is done from scripting using Camera.RenderWithShader or Camera.SetReplacementShader functions. Both functions take a shader and a replacementTag.spa

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:.net

  • If replacementTag is empty, then all objects in the scene are rendered with the given replacement shader.
  • If replacementTag is not empty, then for each object that would be rendered:
    • The real object’s shader is queried for the tag value.
    • If it does not have that tag, object is not rendered.
    • 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.

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 Unity shaders have a 「RenderType」 tag set.3d

 

其中最須要理解的是replacementTag,上面文檔詳細敘述了replacementTag的邏輯,爲了好理解,下面換種說法從新解釋一遍:orm

*假設腳本中調用 GetComponent<Camera>().RenderWithShader(Shader.Find("shaderX"), ""),則此攝像機本次渲染的全部物體都會使用shaderX進行渲染。htm

*假設腳中中調用 GetComponent<Camera>().RenderWithShader(Shader.Find("shaderX"), "myReplacementTag"),則對於本次要渲染的每一個物體object(i),假設object(i)自己的shader是shader(i),若是shader(i)的全部subShader都不帶"myReplacementTag"標籤,則object(i)不渲染;若是shader(i)中的subShader(j)帶有"myReplacementTag"標籤,設此標籤爲"myReplacementTag"="A",則unity會去shaderX中找"myReplacementTag"="A"的subShader,若是找到了,則用shaderX的此subShader替換object(i)的原有shader;不然object(i)不渲染。

須要指出的是,"myReplacementTag"應該老是用"RenderType",緣由是unity內置的全部shader都帶有RenderType標籤。

舉兩個例子:

例1,將全部的不透明物體shader替換爲另外一種shader進行渲染:

寫一個shaderX,讓其中包含一個帶"RenderType"="Opaque"標籤的subShader,

調用GetComponent<Camera>().RenderWithShader(Shader.Find("shaderX"), "RenderType");

例2,將全部不透明物體shader替換爲一種subShader進行渲染,同時將全部透明物體shader替換爲另外一種shader進行渲染:

寫一個shaderX,讓其中包含一個帶「RenderType」="Opaque"標籤的subShader,再寫一個帶"RenderType"="Transparent"標籤的subShader,

調用GetComponent<Camera>().RenderWithShader(Shader.Find("shaderX"), "RenderType");

例3,將全部「RenderType」=「myRenderType」的物體的shader替換爲另外一種shader進行渲染:

寫一個shaderX,讓其中包含一個帶"RenderType"="myRenderType"標籤的subShader,

調用GetComponent<Camera>().RenderWithShader(Shader.Find("shaderX"), "RenderType");

 

另外,關於Camera.RenderWithShader與Camera.SetReplacementShader的區別:

Camera.RenderWithShader只是本次渲染使用替換的shader;Camera.SetReplacementShader是自調用起之後都使用替換的shader進行渲染,直到手動調用Camera.ResetReplacementShader爲止,恢復爲用自己的shader進行渲染。參考;http://m.blog.csdn.net/blog/QUAN2008HAPPY/39380463

 

另外在Camera.RenderWithShader的官方文檔中寫道:

This is used for special effects, e.g. rendering screenspace normal buffer of the whole scene, heat vision and so on. To make use of this feature, usually you create a camera and disable it. Then call RenderWithShader on it.

也就是說,在使用RenderWithShader實現特效時一般應該將調用RenderWithShader這個函數的相機設爲disable,即:GetComponent<Camera>().enabled = false,或者也能夠直接在Inspector中將Camera組件前的對勾去掉,是同樣的效果

相關文章
相關標籤/搜索