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.
 - 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.
 
 
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)的更多相关文章
- unity, 替换shader渲染(Rendering with Replaced Shaders)【转】
		
实现特效,尤其是一些后处理特效,经常需要将各物体的shader替换为另一套shader进行渲染到纹理,再后再进行合成或以某种叠加方式叠加到最后的画面上去. 再复杂一点儿的,可能不同的物体所用的替换sh ...
 - Rendering with Replaced Shaders
		
[Rendering with Replaced Shaders] 1.RenderType tag RenderType tag categorizes shaders into several p ...
 - 使用替换shader渲染
		
相关函数: Camera.RenderWithShader(shader: Shader, replacementTag: string) 使用指定shader渲染,只影响一帧 Camera.SetR ...
 - Unity Lighting - Choosing a Rendering Path 选择渲染路径(三)
		
Choosing a Rendering Path 选择渲染路径 Unity supports a number of rendering techniques, or ‘paths’. An i ...
 - Unity Shader入门精要学习笔记 - 第16章 Unity中的渲染优化技术
		
转自冯乐乐的 <Unity Shader 入门精要> 移动平台的特点 为了尽可能一处那些隐藏的表面,减少overdraw(即一个像素被绘制多次),PowerVR芯片(通常用于ios设备和某 ...
 - 【淡墨Unity3D Shader计划】五 圣诞用品: Unity在Shader三种形式的控制&混合操作编译
		
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/42060963 作者:毛星云(浅墨) ...
 - Three.js粒子特效,shader渲染初探(一篇非常详细的介绍)
		
Three.js粒子特效,shader渲染初探 转载来源:https://juejin.im/post/5b0ace63f265da0db479270a 这大概是个序 关于Three.js,网上有不多 ...
 - Unity Built-In Shader造成的运行时内存暴涨
		
在某个PC项目中使用了大量的材质球, 并且都使用了自带的Standard Shader, 在编辑器运行的时候, 一切良好, 运行内存只在1G左右, 然而在进行AssetBundle打包之后, EXE运 ...
 - Unity酱~ 卡通渲染技术分析(二)
		
前面的话 上一篇Unity酱~ 卡通渲染技术分析(一) 写了CharaMain.cginc,服装的渲染是怎么实现的.这篇来分析一下头发跟皮肤的实现 头发 本来以为unitychan的头发会有各向异性的 ...
 
随机推荐
- tomcat服务器重启后session可以继续使用
			
原文:http://blog.csdn.net/e421083458/article/details/8651312 测试没有效果 配置server.xml文件,加入session保存操作 <C ...
 - Silverlight:《Pro Silverlight5》读书笔记 之 Layout
			
Layout The Layout Containers The Panel Background By default, the Background of a layout panel is se ...
 - Ruby:字符集和编码学习总结
			
背景 Ruby直到1.9版本才很好的支持了多字节编码,本文简单总结了今天学习的关于Ruby编码方面的知识. 字符串可以使用不同的编码 在.NET中字符串的编码是一致的,Ruby允许字符串有不同的编码, ...
 - golang日期时间格式format()
			
format()函数格式化字符串,用了语句time.now().format(“2015-11-12 12:00:00”),结果输出结果就是不能达到理想的结果,然后把golang文档中的”2006-0 ...
 - booksleeve 使用
			
By offering pipelined, asynchronous, multiplexed and thread-safe access to redis, BookSleeve enables ...
 - MVC4 过滤器(转)
			
先来看看一个例子演示过滤器有什么用: public class AdminController : Controller { // ... instance variables and constru ...
 - Error: Finish can only be called once
			
Android studio 启动或者新建项目:报错“Error: Finish can only be called once” gradle缓存问题: 默认的额缓存路径在: on windows ...
 - go语言基础之递归实现数字累加
			
1.实现1+100 = 5050 示例: package main import "fmt" //实现1+2+3+……100 func test01() (sum int) { f ...
 - 主题 Theme 小结
			
主题的使用 默认创建的Android工程中,在AndroidManifest.xml文件中有<application android:theme="@style/AppTheme&qu ...
 - SQL Server Service Broker 简单例子 (转)
			
SQL Server Service Broker服务体系结构 消息类型 — 定义应用程序间交换的消息的名称.还可以选择是否验证消息.约定 — 指定给定会话中的消息方向和消息类型.队列 — 存储消息. ...