实现特效,尤其是一些后处理特效,经常需要将各物体的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组件前的对勾去掉,是一样的效果。

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

  1. unity, 替换shader渲染(Rendering with Replaced Shaders)【转】

    实现特效,尤其是一些后处理特效,经常需要将各物体的shader替换为另一套shader进行渲染到纹理,再后再进行合成或以某种叠加方式叠加到最后的画面上去. 再复杂一点儿的,可能不同的物体所用的替换sh ...

  2. Rendering with Replaced Shaders

    [Rendering with Replaced Shaders] 1.RenderType tag RenderType tag categorizes shaders into several p ...

  3. 使用替换shader渲染

    相关函数: Camera.RenderWithShader(shader: Shader, replacementTag: string) 使用指定shader渲染,只影响一帧 Camera.SetR ...

  4. Unity Lighting - Choosing a Rendering Path 选择渲染路径(三)

      Choosing a Rendering Path 选择渲染路径 Unity supports a number of rendering techniques, or ‘paths’. An i ...

  5. Unity Shader入门精要学习笔记 - 第16章 Unity中的渲染优化技术

    转自冯乐乐的 <Unity Shader 入门精要> 移动平台的特点 为了尽可能一处那些隐藏的表面,减少overdraw(即一个像素被绘制多次),PowerVR芯片(通常用于ios设备和某 ...

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

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/42060963 作者:毛星云(浅墨)  ...

  7. Three.js粒子特效,shader渲染初探(一篇非常详细的介绍)

    Three.js粒子特效,shader渲染初探 转载来源:https://juejin.im/post/5b0ace63f265da0db479270a 这大概是个序 关于Three.js,网上有不多 ...

  8. Unity Built-In Shader造成的运行时内存暴涨

    在某个PC项目中使用了大量的材质球, 并且都使用了自带的Standard Shader, 在编辑器运行的时候, 一切良好, 运行内存只在1G左右, 然而在进行AssetBundle打包之后, EXE运 ...

  9. Unity酱~ 卡通渲染技术分析(二)

    前面的话 上一篇Unity酱~ 卡通渲染技术分析(一) 写了CharaMain.cginc,服装的渲染是怎么实现的.这篇来分析一下头发跟皮肤的实现 头发 本来以为unitychan的头发会有各向异性的 ...

随机推荐

  1. 在w7下的wamp中配置memcache

    php版本是5.4.16 ,我的电脑是w7 64位的. 一. memcache和memcached的区别  在自己的新程序中打算全面应用memcached技术,这个很容易理解这是memcached是内 ...

  2. 怎样解决MySQL数据库主从复制延迟的问题

    像Facebook.开心001.人人网.优酷.豆瓣.淘宝等高流量.高并发的网站,单点数据库很难支撑得住,WEB2.0类型的网站中使用MySQL的居多,要么用MySQL自带的MySQL NDB Clus ...

  3. linux、mac的bash和zsh如何切换

    1.hostname 192-23-2-2 修改主机名字 2.chsh -s /bin/bash和chsh -s /bin/zsh可以永久切换,也就是一登录进来的就是相应的界面 bash/zsh命令是 ...

  4. Junit Hamcrest Mockito单元测试

    pom.xml配置 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...

  5. C#常见算法题目

        //冒泡排序    public class bubblesorter    {        public void sort(int[] list)        {            ...

  6. Quartz学习笔记

    :30发送email通知客户最新的业务情况. java.util.Timer和java.util.TimerTask    Timer和TimerTask是能够完毕job schedule的两个jdk ...

  7. SSH免密码登陆以及穿越跳板机

    1. 免密码直连  [user@hostA ~] $ssh hostB STEP1. 在hostA上生成RSA公钥私钥(在~/.ssh/下生成RSA私钥id_rsa,公钥id_rsa.pub) [us ...

  8. 步步为营_Android开发课[3]_Activity学习

    Focus on technology, enjoy life! -- QQ:804212028 浏览链接:http://blog.csdn.net/y18334702058/article/deta ...

  9. 【iOS开发-59】LOL案例:单组tabView、alertView样式、实现监听,以及用reloadData数据刷新

    案例效果: (1)先在storyboard中拖拽出一个tableView,然后下面用代码. --tableView继承自scrollView.所以自然有滚动的特性 --最基本的还是数据转模型.以及对c ...

  10. LoadRunner录制:事务

    背景 LoadRunner 会对事务的性能指标进行记录. 添加事务也是为了在测试的时候统计这段脚本运行时用的时间等等,方便定位性能瓶颈. 一个事务可以包含一个请求,也可以包含多个请求.一般把完成一件事 ...