unity, 替换shader渲染(Rendering with Replaced Shaders)

实现特效,尤其是一些后处理特效,经常需要将各物体的shader替换为另一套shader进行渲染到纹理,再后再进行合成或以某种叠加方式叠加到最后的画面上去。

再复杂一点儿的,可能不同的物体所用的替换shader还不一样。

unity中Camera.RenderWithShader可实现这个功能。

下面是官方文档原话:

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.

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

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.
  • 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.

其中最需要理解的是replacementTag,上面文档详细叙述了replacementTag的逻辑,为了好理解,下面换种说法重新解释一遍:

*假设脚本中调用 GetComponent<Camera>().RenderWithShader(Shader.Find("shaderX"), ""),则此摄像机本次渲染的所有物体都会使用shaderX进行渲染。

*假设脚中中调用 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组件前的对勾去掉,是一样的效果。

时间: 2024-10-17 09:24:21

unity, 替换shader渲染(Rendering with Replaced Shaders)的相关文章

Rendering with Replaced Shaders

[Rendering with Replaced Shaders] 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: Rendering with Replaced Shaders

使用替换shader渲染

相关函数: Camera.RenderWithShader(shader: Shader, replacementTag: string) 使用指定shader渲染,只影响一帧 Camera.SetReplacementShader(shader: Shader, replacementTag: string) 使用指定shader替换,直接替换掉物体的渲染shader Camera.ResetReplacementShader() 重置替换shader,也就是将物体的渲染shader还原为物体

【浅墨Unity3D Shader编程】之五 圣诞夜篇: Unity中Shader的三种形态对比&amp;混合操作合辑

本系列文章由@浅墨_毛星云 出品,转载请注明出处.  文章链接:http://hpw123.net/a/C__/kongzhitaichengxu/2014/1222/164.html 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] QQ交流群:330595914 更多文章尽在:http://www.hpw123.net 本文算是固定功能Shader的最后一篇,下一次更新应该就会开始讲解表面Shader,而

【淡墨Unity3D Shader计划】五 圣诞用品: Unity在Shader三种形式的控制&amp;amp;混合操作编译

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/42060963 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] 文章开头,先给自己诚求个游戏研发实习的好去处. 浅墨今年1月.明年上半年有近半年的空暇时间可供实习. 近5年游戏编程经验,能够胜任全职的游戏开发工作.仅仅拿实习生的工资(性价比非常高有

Unity的shader学习2

下面继续看基于surface的shader代码,基本与Vertex&Fragment shader差不多,只是不能写pass,然后只需要声明surface函数,就能处理所有的事情. 1 Shader "T1/Hero/Diffuse" { 2 Properties { 3 _MainTex ("Base (RGB)", 2D) = "white" {} 4 _Color ("Main Color", Color) =

Unity Geometry Shader实现

unity官方文档关于geometry shader的内容等同于没有,这也是因为unity的开发者基本面向的是移动平台开发,所以这种SM4.0的特性基本都不会被开发者考虑.但是本着与时俱进的精神(虽然现在已经不早了)还是研究一下以备不时之需. 在开始unity geometry shader之前,通过DX10的龙书,简单的了解了一下geometry shader的原理.然后看了一个GS的billboard例子,觉得大同小异. 首先要知道,GS和VS以及FS的区别. 在dx9的渲染管线中,可编程的

蛋哥的学习笔记之-基于Unity的Shader编程:X-1 音乐水波特效

蛋哥的学习笔记之-基于Unity的Shader编程:X-1 音乐水波特效 热度 13728 2015-7-11 23:34 |个人分类:蛋哥的学习笔记之-基于Unity的Shader编程| 音乐, Unity, Shader, 水波, Shader, Shader, Shader, Shader 一.要干些啥: 很久很久没有写文档了,前段时间做了个个人很喜欢的,自认为比较原创的小特效,所以写个文档纪念下(本人特别喜欢音乐) 思路其实很简单,首先用顶点着色器实现一般的水波特效,然后解析音频数据(我

【Unity灯光与渲染技术】Global Illumination全局光照

本系列主要参考Unity灯光与渲染技术教程Unity Lighting And Rendering,同时会加上一点个人实践过程和理解. ========================================== 分割线 ========================================== 这篇文章主要讲全局光照,在看教程的时候就有一个点不是很理解,就是作者开启物体的static这个选项.在网上查找一些资料,有的说"static表示物体时静态的,多用于静止不动的物体,此外

Unity 切换Shader耗CPU大

在游戏中,怪物或者人受到攻击后,会有变白的效果.这个效果是Shader实现的.在判定被攻击的时候切换Shader. Shader shader = getBeAttackShader(); material.shader = shader; static Shader s_BeattackShader = null; protected virtual Shader getBeAttackShader() { if(s_BeattackShader == null) { s_BeattackSh