Unity Post-Processing的一些分享
讲些什么?
绝大多数的游戏或多或少都会使用些后处理效果.
早期版本中,Unity在提供的接口有限,优化空间不大,属于放任自流。官方推出了Post-Processing(下文简称PP)并在Github上长期维护,很好的将后处理与其提供的一些新的渲染API结合起来。无论是在易用性还是性能上都要比以前好。
本文主要针对于PP的自定义扩展上进行一些讨论。只有当需要添加新的自定义效果或者修改PP内置效果时才需要考虑这些问题。顺便连带着提一提涉及到的Unity新的渲染概念。
由PostProcessEvent引出
为了能正确理解下文讨论的内容,需阅读链接处Wiki上的文字了解添加自定义后处理的步骤。你会首先看到PostProcessEvent这个枚举,这个枚举是贯穿始终的。
public enum PostProcessEvent
{
BeforeTransparent = ,
BeforeStack = ,
AfterStack = ,
} ... public PostProcessAttribute(Type renderer, PostProcessEvent eventType, string menuItem, bool allowInSceneView = true)
{
...
builtinEffect = false;
} internal PostProcessAttribute(Type renderer, string menuItem, bool allowInSceneView = true)
{
...
builtinEffect = true;
}
PP会根据枚举标记将所有后处理归类放到不同的序列,序列之间最大差异是执行顺序问题(这同引擎渲染的RenderQueue类似)。
问:第一次看到BeforeStack和AfterStack会有疑惑,这里的Before和After是相对于什么的?
答:注意上面这个Attribute的构造函数重载代码中后面一种重载没有指定eventType,但是将builtinEffect赋为true.实际上builtinEffect这个布尔变量暗含着一个Built-in Stack的序列(Wiki中解释了常见的Vignette,Bloom等都属于这个序列).
为什么要分不同序列
有两个主要原因:
1.方便扩展:
后处理效果是对执行顺序敏感的,比如不想影响特效(大多数为半透明),那就需要标记为BeforeTransparent,以保证后处理发生在所有半透明物体绘制之前。
有了CommandBuffer之后,Unity提供了更多可选择的渲染时机,PP进行简化。
如下图,Unity提供的几个序列,实际上就是方便你将自己的后处理选择一个适合的渲染时机。

2.提高性能
同一个序列内的后处理效果大概率对资源存在复用可能,特别是RenderTarget。虽然单像素的计算复杂度对后处理有影响,但频繁的切换RenderTarget(俗称翻Buffer)造成更大且不必要的开销。
用FrameDebugger去查看后处理的各个Pass,会发现一个叫Uber的步骤,Uber不对应某个具体效果,它是个特殊的Pass,通过将之前分散在各个后处理着色器中的渲染逻辑整合到一起,并利用ShaderKeywords来进行代码段的屏蔽开启。从而最大程度上提高资源复用,降低DC。
我画了个图,看上去更直观,左侧是优化前,右侧是优化后的,无论是DrawCall,还是对RenderTexture的使用都由性能提升。

如何整合
打开Uber.shader,会看到里面都是Built-in Stack的内容,如果你自定义的后处理Shader,
如果你自定义的后处理仅需一个DC或存在与内置效果有共用资源的情况,那就尽量将其整合入Uber中.
整合过程中提几个需要注意的地方:
1.自定义的后处理脚本中要使用正确的PostProcessAttribute重载。
2.将片元着色器逻辑整合进Uber.shader的FragUber函数中时,注意与其它效果间的顺序,若不是常驻效果,应该通过Keyword来提供开关。
3.PP提供的Shader中大多引其自带的cginc文件,很多平时常用的函数都不存在,需要自行添加。
每一个引擎都需要解决如何最合理和高效的提供后处理的接口。Unity提供的PP源代码值得一看。
提及两个概念
PP的设计是基于CommandBuffer的,并大量使用了MaterialPropertyBlock。这里略带提及一下这两个概念
1.CommandBuffer(CB)

CB就是缓存将一系列渲染命令,在一个合适渲染阶段进行执行。这些阶段可以查看CameraEvent这个枚举:可见Unity考虑的很周到,大多数渲染阶段都提供了,这个东西还是该点赞的。
重点看CameraEvent,BuiltinRenderTextureType,CommandBuffer这几个API文档
2.MaterialPropertyBlock(MPB)
MaterialPropertyBlock is used by Graphics.DrawMesh and Renderer.SetPropertyBlock. Use it in situations where you want to draw multiple objects with the same material, but slightly different properties. For example, if you want to slightly change the color of each mesh drawn. Changing the render state is not supported.
这是文档的一段说明,Unity建议用MPB的API去替换掉传统的Material.setXXX,有用户测试过,提升还是蛮大的。猜测Unity应该是对材质管理和图形API底层Shader赋值的结构上进行了优化,降低了不必要的查找,拷贝等。
以上是近日来在实际工作上的一点分享,希望自己日后有精力时,在后处理方面有更多分享。如果你有任何不同的理解或意见,欢迎留言。
尊重他人智慧成果,非本人同意,请勿转载
Unity Post-Processing的一些分享的更多相关文章
- Unity多媒体展示项目经验分享-ImageEffect+动态绑定
Unity多媒体展示项目经验分享-ImageEffect+动态绑定+网络通信 <ignore_js_op> “海尔科技展墙”是去年年初我们为上海家电博览会制作的一个多媒体展项,有限的工期以 ...
- Unity MMORPG游戏优化经验分享
https://mp.weixin.qq.com/s/thGF2WVUkIQYQDrz5DISxA 今天由Unity技术支持工程师高岩,根据实际的技术支持工作经验积累,分享如何对Unity MMORP ...
- Unity接入微信登录 微信分享 微信支付 支付宝SDK
你将会学到的unity集成SDK游戏中接入微信支付与支付宝支付游戏中接入微信登录与微信分享 目录 mp4格式,大小2.2GB 扫码时备注或说明中留下邮箱 付款后如未回复请至https://shop13 ...
- 【Unity入门】编辑器常用视图介绍
版权声明:本文为博主原创文章,转载请注明出处. 打开Unity编辑器的主窗口,在窗口的右上角可以看到有个“Layout”按钮.这是用来对Unity编辑器主窗口上面的各个窗口面板进行布局的.通常情况下我 ...
- 如何在Unity中分别实现Flat Shading(平面着色)、Gouraud Shading(高洛德着色)、Phong Shading(冯氏着色)
写在前面: 先说一下为什么决定写这篇文章,我也是这两年开始学习3D物体的光照还有着色方式的,对这个特别感兴趣,在Wiki还有NVIDIA官网看了相关资料后,基本掌握了渲染物体时的渲染管道(The re ...
- Unity User Group 北京站:《Unity5.6新功能介绍以及HoloLens开发》
时间一转眼从春天来到了初夏,Unity User Group(以下简称UUG)活动也迎来了第七期.我们面向Unity3D开发从业者以及未来想从事Unity3D开发的学生群体的UUG活动这次仍然在海淀 ...
- Re:Unity游戏开发有哪些让你拍案叫绝的技巧?
这是我在知乎一个问题: <Unity游戏开发有哪些让你拍案叫绝的技巧?> 下面的回答,觉得蛮有趣的,贴在这里和博客的朋友们分享下. ----- 分享一个比较好玩的内容吧. 大家都知道Uni ...
- Unite 2017 | Unity引擎发展四大方向
Unite 2017 Shanghai已落幕,今天为大家分享本次大会备受关注的Keynote主题演讲.本次大会Keynote主题演讲聚焦了Unity全球领导团队,包括Unity创始人David Hel ...
- BEST FREE UNITY ASSETS – OVER 200 CURATED QUALITY ASSETS
http://www.procedural-worlds.com/blog/best-free-unity-assets-categorised-mega-list/ BEST FREE UNITY ...
- Unite Beijing 2015大型活动
摘要:2015年,我做的最疯狂的事情:网友见面会—去北京参加Unite Beijing 2015大会. 正文:记得,上次在北京参加大型活动还是2008年前–传统电信行业的巅峰时期:那时移动互联网.An ...
随机推荐
- ros 使用笔记
1. publishers/subscribers 常用指令 说明rosnode list 查看所有激活的节点rostopic list 查看所有激活的topicrostopic i ...
- 本地新建git仓库后与远端仓库关联
背景说明:如果你想把自己的一个项目开源到,需要新建一个本地代码仓库,然后与远端代码库建立关.不想使用git clone 命令去克隆远端新建代码仓库,然后再将我们写好的代码copy到克隆下来的文件夹里, ...
- Python学习之路基础篇--11-12Python基础,函数的装饰器
对于装饰器来说,就是在不改变函数的调用的情况下,对函数的前后增加了些许功能,这完全符合函数的 开放封闭 原则.装饰器的本质 其实就是一个闭包函数. 这是一个装饰器的步骤图 ret = func(*ar ...
- width属性
宽度属性 width:长度值|百分比|auto 最大宽度:max-width 最小宽度:min-width 说明:设置块级元素和替换元素的内容宽度.
- Egret_时间与运行
1.加载资源 2.将显示对象添加到显示列表 /////////////*****************************动态帧频******************************** ...
- http协议常见状态码含义
状态码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值: 2xx:成功--表示请求已被成功接收.理解.接受 200(成功) 服务器已成功处理了请求.通常,这表示服务器提供了请求的网页. ...
- SQLI DUMB SERIES-13
(1)检测闭合方式 通过 ') 闭合. (2)尝试输入 admin')# 无回显.尝试报错注入, 爆表payload: admin') and extractvalue(1,concat(0x7e,( ...
- mybatis:Parameter 'ids' not found.
https://www.cnblogs.com/baby-lijun/p/5908088.html ps:根本原因就是他们根本就没有理解foreach里面的collection应该放什么东西,错误的理 ...
- socks5服务器编写经验总结
一.Socks5服务器实现设计 本Socks5服务器是之前做的一个项目中的一个小部分东西,该项目是一个可以实现多级转发代理网络通讯的项目,能够隐藏网络数据包的源IP地址和端口,能够为上网的用户提供安全 ...
- Ubuntu 16.04 强制使用ipv4安装apt-get
参考文献:https://www.linuxidc.com/Linux/2015-09/123340.htm 起因:每次校园网都要自动用ipv6不知道为什么又总之链接不上,导致安装失败,有以下命令强行 ...