讲些什么?


  绝大多数的游戏或多或少都会使用些后处理效果.

  早期版本中,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的一些分享的更多相关文章

  1. Unity多媒体展示项目经验分享-ImageEffect+动态绑定

    Unity多媒体展示项目经验分享-ImageEffect+动态绑定+网络通信 <ignore_js_op> “海尔科技展墙”是去年年初我们为上海家电博览会制作的一个多媒体展项,有限的工期以 ...

  2. Unity MMORPG游戏优化经验分享

    https://mp.weixin.qq.com/s/thGF2WVUkIQYQDrz5DISxA 今天由Unity技术支持工程师高岩,根据实际的技术支持工作经验积累,分享如何对Unity MMORP ...

  3. Unity接入微信登录 微信分享 微信支付 支付宝SDK

    你将会学到的unity集成SDK游戏中接入微信支付与支付宝支付游戏中接入微信登录与微信分享 目录 mp4格式,大小2.2GB 扫码时备注或说明中留下邮箱 付款后如未回复请至https://shop13 ...

  4. 【Unity入门】编辑器常用视图介绍

    版权声明:本文为博主原创文章,转载请注明出处. 打开Unity编辑器的主窗口,在窗口的右上角可以看到有个“Layout”按钮.这是用来对Unity编辑器主窗口上面的各个窗口面板进行布局的.通常情况下我 ...

  5. 如何在Unity中分别实现Flat Shading(平面着色)、Gouraud Shading(高洛德着色)、Phong Shading(冯氏着色)

    写在前面: 先说一下为什么决定写这篇文章,我也是这两年开始学习3D物体的光照还有着色方式的,对这个特别感兴趣,在Wiki还有NVIDIA官网看了相关资料后,基本掌握了渲染物体时的渲染管道(The re ...

  6. Unity User Group 北京站:《Unity5.6新功能介绍以及HoloLens开发》

    ​时间一转眼从春天来到了初夏,Unity User Group(以下简称UUG)活动也迎来了第七期.我们面向Unity3D开发从业者以及未来想从事Unity3D开发的学生群体的UUG活动这次仍然在海淀 ...

  7. Re:Unity游戏开发有哪些让你拍案叫绝的技巧?

    这是我在知乎一个问题: <Unity游戏开发有哪些让你拍案叫绝的技巧?> 下面的回答,觉得蛮有趣的,贴在这里和博客的朋友们分享下. ----- 分享一个比较好玩的内容吧. 大家都知道Uni ...

  8. Unite 2017 | Unity引擎发展四大方向

    Unite 2017 Shanghai已落幕,今天为大家分享本次大会备受关注的Keynote主题演讲.本次大会Keynote主题演讲聚焦了Unity全球领导团队,包括Unity创始人David Hel ...

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

  10. Unite Beijing 2015大型活动

    摘要:2015年,我做的最疯狂的事情:网友见面会—去北京参加Unite Beijing 2015大会. 正文:记得,上次在北京参加大型活动还是2008年前–传统电信行业的巅峰时期:那时移动互联网.An ...

随机推荐

  1. echarts 滚动条 缩放

    // 初始化是否需要展示滚动条,与初始显示的数据数(总数据数的百分比) var isShowScroll = false;// 是否显示滚动条,默认false不显示 var dataZoom_end; ...

  2. crunch--字典生成工具

    Crunch是一种创建密码字典工具,按照指定的规则生成密码字典,可以灵活的制定自己的字典文件.使用Crunch工具生成的密码可以输出到屏幕,保存到文件.或另一个程序.crunch程序在2004年及以前 ...

  3. ckeditor_学习(2) 功能概览

    这篇文章用来说明 ckeditor 的所有可配置的功能,分为终端用户配置和开发者配置 1.终端用户配置 用户接口 – 设置编辑器的UI和语言 Editor 尺寸设置 – 设置编辑器的尺寸 插入内容 – ...

  4. java native 笔记

    java中native的用法   前言: 在查看 Object.java 文件时,发现有一个 方法比较特殊(不认得,看不懂...)  private static native void regist ...

  5. seriviceWorker 小结

    serviceWorker 的状态 install → activate. 1.初进页面,此前未加载过serviceWorker,直接进入install状态,随后进入activate状态,但是此时se ...

  6. 锚点的animate使用过程中定位不准确的问题小记

    源码: $('html, body, .S').animate({ scrollTop: $('.a1').offset().top - 133}, { duration: 1500, easing: ...

  7. 1. Packet sniffers (包嗅探器 14个)

    十多年来,Nmap项目一直在编目网络安全社区最喜爱的工具. 2011年,该网站变得更加动态,提供打分,评论,搜索,排序和新工具建议表单. 本网站除了我们维护的那些工具(如Nmap安全扫描器,Ncat网 ...

  8. [工作积累] Google Play Services

    注意添加APP_ID <meta-data android:name="com.google.android.gms.games.APP_ID" android:value= ...

  9. 树莓派中transmission的blocklist

    /var/lib/transmission-daemon/.config/transmission-daemon/blocklists 使用root账户进入这个目录,新建文件ip ipv4:0.0.0 ...

  10. python中使用if __name__ == '__main__':

    引子 在python中,假设在一个test1.py的模块中定义了一个foo函数,然后调用函数foo进行测试的时候会产生一个内存空间.当你把这个模块导入到test2.py模块中,接下来如果在test2. ...