走进LWRP(Universal RP)的世界

走进LWRP(Universal RP)的世界 

原文:https://connect.unity.com/p/zou-jin-lwrp-universal-rp-de-shi-jie

LWRP自Unity2018发布以来,进入大家视野已经有一段时间了,不过对于广大Unity开发者来说,依然相对比较陌生,原因有几个,一是一直以来LWRP都处于预览状态,使用中会遇到一些bug,所以也就止于尝试。第二个原因就是LWRP的升级跨度太大,基本所有的shader都需要重写,所有的材质球都得重新调整,这对于已经开始进入Production 阶段的项目来说是不可接受的。

最近有幸在项目中使用LWRP,经过好几个月的使用,回过来看发现目前不少用户对于LWRP的认识与实际会有不少出入,加之目前关于LWRP的分享大多仅仅是对于其Shader和材质球用法的教程,很少有从原理上介绍LWRP的文章。因此想借着这篇文章,跟大家分享一下这几个月使用的心得,和踩过的坑。

 

从LWRP到Universal RP

为什么我要在最开头说这个话题呢,原因是LWRP这个名字即将退出历史的舞台,从2019.3开始,LWRP将会以Universal RP的名字跟大家见面。

当然,最根本的原因是LWRP这个名字给使用者带来了不少误导和困扰,这也是Unity官方要对管线进行重命名的原因。LW是轻量级的缩写,大家听到这个名字,以及Unity最初对这个管线的宣传,都给大家带来了这个管线是专为移动游戏简化并且高度优化的一个管线。换句话说,我们大家都以为,只要换了LWRP,妈妈再也不用担心做出来的手游卡了。

 

费尽千辛万苦,将测试场景从内置管线转换成LWRP之后,我迫不及待的跑了一波性能测试,测试结果emmmmm…

 

 

无论在简单还是复杂的场景里,最终的渲染耗时和帧率,并没有发现有什么肉眼可见的性能提升,仿佛之前转换管线是自己想象出来的,其实并没有切换管线。

然而这肯定是不可能的,事实上其实是我并没有搞清楚LWRP的设计初衷和他的优劣势,于是痛定思痛,我决定从图形学开始补习,并把LWRP的原理摸透

 

Universal RP的优势

之前有讲到Unity已经正式将LWRP的名称变更为Universal RP——即通用渲染管线,并将正式接过内置管线的大旗,成为新一代Unity的兼容所有平台的通用渲染管线。

大家肯定都会跟我有一样的疑惑,内置管线不是本来就跨平台好好的么,Universal RP也没看出来性能上有什么特别的优势,干嘛放着好好的又稳定的内置管线不用,要跑来折腾什么URP。其实这个问题的关键在于,我们之前的打开方式不对。

 

URP在性能上的优势

说到性能优势,那首先我们就必须得弄清楚,到底在哪种情况下,URP的哪一方面会有性能优势。要对比性能那就首先要比较一下,URP跟内置管线到底在渲染上有什么区别。

1、渲染路径的差别

其中,最大的一点区别是,URP是单Pass前向渲染管线,而内置管线是多Pass前向渲染管线和延迟渲染管线

URP没有延迟渲染,因此我们只对比前向渲染这一项(其实手游也基本只会用前向渲染,延迟渲染的G-Buffer所需要的带宽带来的开销太大)。

所谓的前向渲染,就是在渲染物体受点光光照的时候,分别对每个点光对该物体产生的影响进行计算,最后将所有光的渲染结果相加得到最终物体的颜色。内置管线的做法是,用多个pass来渲染光照,第一个pass只渲染主光源,然后多出来的光每个光用一个pass单独渲染。这也是为什么我们在做手游的时候很少会用点光源。因为对于内置管线来说,每多一盏光,整个场景的drawcall就会翻倍,这个性能开销基本是无法接受的。

URP的做法则是,在一个pass当中,对这个物体受到的所有光源通过一个for循环一次性计算。这么做的好处有:

  1. 一个物体的光照可以在一次DrawCall中计算完毕

  2. 省去了多个Pass的上下文切换以及光栅化等开销

但是这么做的坏处也很明显:

  1. 只支持1盏直光

  2. 单个物体最多支持4盏点光

  3. 单个相机最多支持16盏灯光

因此,有了URP之后,只要控制好点光的范围,我们在手游里面也可以做多点光照明了,例如释放一个火球照亮周围物件,这在内置管线里基本是可以放弃的功能(或者用其他作假的方式模拟)

2、GrabPass

还有一个内置管线中,很难运用到手游中的技术,那就是GrabPass

这个技术通常会用来制作空气扰动或者刀光等特效带来的折射效果,在内置管线中如果使用这个功能,则会在每个用到这个Shader的地方对屏幕缓冲区进行一次抓取操作, 这个操作会大幅消耗GPU的带宽。 在移动设备上带宽是非常有限的资源,因此这个效果在手机上几乎是没法使用的

在URP中,可以在渲染管线的配置文件中,开启Opaque Texture,这张图是管线在完成不透明物体渲染后,将屏幕缓冲区中(也可能是相机的ColorRT)的颜色信息抓取出来保存到一张单独的RT当中,然后在特效中就可以直接拿这张图去进行扭曲和扰动计算。

 

 

这么做的好处就是可以将抓取操作的次数恒定下来,不会因为同屏有多少个需要扰动的对象而额外增加开销。当然坏处也比较明显,那就是没办法对不透明物体进行扰动操作了,也就是说只能对场景物件而没法对特效进行扰动。

而且Unity非常贴心的在URP的粒子特效Shader当中直接内置了扰动的效果,通过勾选框就能开启了

3、SRP Batcher

在所有SRP管线中(URP和HDRP或者你自己的自定义管线),都可以受益于SRP Batcher,这个功能可以将没有进行静态合并,也没法通过Instancing渲染的使用相同Shader的物体,通过CBuffer去保存每个物体材质球的参数,进而在不进行SetPassCall的情况下完成绘制。这个功能的效果是,可以大幅降低相同DrawCall情况下单个DrawCall的开销,当这个功能开启的时候,你会发现,也许你的场景有500个DrawCall,但实际上SetPassCall只有不到100,在相同情况下的渲染性能是要高于内置管线不少的。不过Shader要支持SRP Batcher还是有些条件的,详细的大家去参考SRP Batcher的文档吧

 

URP在扩展性上的优势

Unity提出SRP,其中一个最大的初衷就是提高渲染管线的灵活性,给使用者提供最大的自定义空间来满足各个项目的需求。要想一个渲染管线满足所有类型项目的需求,这根本就是不可能的,这必然会造成对性能或者功能上的妥协。

因此URP自然而然的具备了非常强大的可扩展性,其大多数功能都是完全模块化的,可以自由搭配组合,而且对她进行扩展大多数情况下是不需要修改URP本身源码的!

1、RenderFeature/RenderObject

这个功能是LWRP6.x之后加入的新功能,其中RenderObject是RenderFeature的一个默认实现,可以让大家在不写一行代码的情况下对渲染管线进行扩展。

为了使用RenderObject,我们首先需要建立一个新的前向渲染器的配置文件

 

在项目文件夹中右键创建,找到ForwardRenderer这个选项

 

第二步是在刚创建的前向渲染器配置中添加一个新的RenderObject

然后我们就可以看见,我们可以指定一个Layer,然后对这一层的物件使用指定的材质球再在某个特定的时间点(比如渲染完不透明物体后)再进行一次统一的绘制。

这个功能能用来做什么呢? 比如主角的遮挡透明,在内置管线中我们只能用2个Pass来做这个事情,而且因为被遮挡时的显示是半透,所以需要严格控制渲染顺序不然就会在不少情况穿帮,在内置管线中可能会需要手动修改一系列shader的renderqueue来保证最终的显示正确,非常麻烦。 但是在URP中,利用RenderObject就能非常轻松愉快的实现这个功能。

Unity还提供了不少利用RenderObject实现的效果的例子,大家可以移步Github:https://github.com/Unity-Technologies/LWRP-CustomRendererExamples

那RenderFeature又是什么呢? RenderFeature提供了比RenderObject更低一级的自定义,用户通过继承RenderFeature,可以通过代码手动在自己需要的地方加入自定义Pass,去做自己想做的事情,写完Feature和Pass之后就能跟RenderObject一样,在渲染器设置里通过加号添加上去了。由于使用RenderFeature完全看项目需求,因此在这里就不详细展开了

2、ScriptableRenderer

URP还支持你对ScriptableRenderer进行继承,从而实现一个完全自己的Renderer(自带的ForwardRenderer就是一个实现),因此如果你足够强,完全可以自己写个延时渲染器出来,最棒的是,他已经实现的Pass可以随便抓来用,避免去写一些重复的东西。因此如果大家对管线中有任何不爽的地方或者觉得没必要的地方,大可自由裁切和扩展,自己的项目需要啥咱就用啥,不需要啥就砍啥,主动权完全抓在自己手里!

 

总结

现在回过头看最开始的性能试验,其实并不是因为LWRP没用,而是我当时的测试场景并没有使用到能带来提升的功能(例如点光,扭曲等),这些效果其实在默认管线时期都是压根不会去想用的效果因为根本跑不动。希望大家在看了这篇文章后,能对新的管线有哪些优势以及适合用在哪些地方有个更深入的了解,然后再根据大家的项目需求进行取舍。这也是为什么我最初说LWRP这个名字给大家带来了很多误解和困惑,因为LWRP性能好,并不是因为他轻量,而是因为他实现就不一样,他选择了一条可伸缩性和适配性更强的实现方式,因此新名字Universal RP,比LWRP能更好的说明他的目的和作用。

 

使用中遇到的坑

 

多相机叠加

这应该是使用URP过程中遇到的最大的坑,多相机叠加对于UI来说至关重要,不支持这个也就相当于不支持在UI上放3D模型和特效,不支持这个基本上对于国内的用户来说就相当于没法用了

好在Unity官方已经确认即将加入多相机叠加功能,并在2019.3中正式实现。在等待19.3的这段时间,跟大家分享一个强制开启多相机叠加的方法,以方便大家提前入坑。 其实方法简单到只需要注释3行代码!

打开ScriptableRenderer.cs(适用用LWRP6.7以上,也许以下也行,需要大家自己看),找到GetCameraClearFlag这个方法,按照下面的方法注释掉对应的3行代码

 

 

注释完上面的3行代码后,只需要确保第二个相机的Background Type为Don't Care,并且将Opaque Texture和Depth Texture设置为Off,然后就能开心的使用UGUI的Screen Space-Camera了。 不过上面的修改只能保证Editor和PC平台下的显示正常,手机上的支持需要大家等Unity官方的新版本,或者也可以尝试自行修改LWRP的源码,应该也能改好

 

版本升级带来的重构

LWRP在升级过程中发生了2次大幅重构,一次是5.x过后将原本的_MainTex等变量名修改为了_BaseMap,第二次是将LWRP更名为UniversalRP。

最痛苦的是第一次更名,直接导致我们很多使用自定义shader的材质球报废…… 主贴图都找不到了,虽然Unity提供了升级工具,但是只对使用内置Shader的材质球起效……

第二次更名带来的影响就小不少了,只是命名空间变更,Unity也提供了升级工具,理论上不会出现特别大的问题,但是自己修改过的东西难免还是得手动处理下

 

TLDR;版

LWRP/URP是个非常值得大家尝试的管线,目前的稳定性也已经足够用于商业项目,他所带来的扩展性绝对是用过就会爱上的。充分了解LWRP的特性之后,相信大家能更进一步提升项目的表现力和性能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/246221.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity 2017 Game Optimization 读书笔记(1)Scripting Strategies Part 1

1.Obtain Components using the fastest method Unity有多种Getcomponet的方法&#xff1a; GetComponent(string), GetComponent<T>() GetComponent(typeof(T)) 哪种效率最高会跟随Unity版本的变化而变化&#xff0c;对于Unity 2017&#xff0c;本书作者的测试是Ge…

C# 多态相关的文章

一 C# 多态的实现 封装、继承、多态&#xff0c;面向对象的三大特性&#xff0c;前两项理解相对容易&#xff0c;但要理解多态&#xff0c;特别是深入的了解&#xff0c;对于初学者而言可能就会有一定困难了。我一直认为学习OO的最好方法就是结合实践&#xff0c;封装、继承在…

C++ 虚函数和虚表

几篇写的不错的文章&#xff0c;本文是整合了这几篇文章&#xff0c;感谢这些大佬 https://www.jianshu.com/p/00dc0d939119 https://www.cnblogs.com/hushpa/p/5707475.html https://www.jianshu.com/p/91227e99dfd7 多态: 多态是面相对象语言一个重要的特性,多态即让同一…

Unity 2017 Game Optimization 读书笔记(2)Scripting Strategies Part 2

1. Share calculation output 和上一个Tip很像&#xff0c;可以缓存计算结果或者各种信息&#xff0c;避免多次重复的计算&#xff0c;例如在场景里查找一个物体&#xff0c;从文件读取数据&#xff0c;解析Json等等。 容易忽略的点是常常在基类了实现了某个方法&#xff0c;在…

Unity 2017 Game Optimization 读书笔记(3)Scripting Strategies Part 3

1.Avoid retrieving string properties from GameObjects 通常来讲&#xff0c;从C#的object中获取string 属性没有额外的内存开销&#xff0c;但是从Unity中的Gameobject获取string属性不一样&#xff0c;这会产生上一篇讲到的 Native-Managed Bridge&#xff08;Native内存和…

Unity 2017 Game Optimization 读书笔记(4)Scripting Strategies Part 4

1.Avoid Find() and SendMessage() at runtime SendMessage() 方法和 GameObject.Find() 相关的一系列方法都是开销非常大的。SendMessage()函数调用的耗时大约是一个普通函数调用的2000倍&#xff0c;GameObject.Find() 则和场景的复杂度相关&#xff0c;场景越复杂&#xff0…

Unity HDRP中的光照烘焙测试(Mixed Lighing )和间接光

部分内容摘抄自&#xff1a;https://www.cnblogs.com/murongxiaopifu/p/8553367.html 直接光和间接光 大家都知道在Unity中&#xff0c;我们可以在场景中布置方向光、点光、聚光等类型的光源。但如果只有这些光&#xff0c;则场景内只会受到直接光的影响&#xff0c;而所谓的…

聊聊Unity项目管理的那些事:Git-flow和Unity

感谢原作者https://www.cnblogs.com/murongxiaopifu/p/6086849.html 0x00 前言 目前所在的团队实行敏捷开发已经有了一段时间了。敏捷开发中重要的一个话题便是如何对项目进行恰当的版本管理。项目从最初使用svn到之后的Git One Track策略再到现在的GitFlow策略&#xff0c;中…

聊聊网络游戏同步那点事

写的非常好的一篇博文&#xff0c;转载自https://www.cnblogs.com/murongxiaopifu/p/6376234.html 0x00 前言 16年年底的时候我从当时的公司离职&#xff0c;来到了目前任职的一家更专注于游戏开发的公司。接手的是一个platform游戏项目&#xff0c;基本情况是之前的团队完成…

Unity 2017 Game Optimization 读书笔记 Dynamic Graphics(1)

The Rendering Pipeline 渲染表现差有可能取决于CPU端&#xff08;CPU Bound&#xff09;也有可能取决于GPU(GPU Bound).调查CPU-bound的问题相对简单&#xff0c;因为CPU端的工作就是从硬盘或者内存中加载数据并且调用图形APU指令。想找到GPU-bound的原因会困难很多&#xff…

Unity 2017 Game Optimization 读书笔记 Dynamic Graphics(2)

Lighting and Shadowing 现代的游戏中&#xff0c;基本没有物体能在一步就完成渲染&#xff0c;这是因为有光照和阴影的关系。光照和阴影的渲染在Fragment Shader中需要额外的pass。 首先要设置场景中的Shadow Casters和Shadow Receivers&#xff0c;Shadow Casters投射阴影&…

Unity 2017 Game Optimization 读书笔记 The Benefits of Batching

batching&#xff08;合批&#xff09; 和大量的描述一个3D物体的数据有关系&#xff0c;比如meshes&#xff0c;verices&#xff0c;edges&#xff0c;UV coordinates 以及其他不同类型的数据。在Unity中谈论batching&#xff0c;指的是用于合批mesh数据的两个东西&#xff1a…

Unity 2017 Game Optimization 读书笔记 Dynamic Graphics (3)

Rendering performance enhancements Enable/Disable GPU Skinning 开启GPU Skinning可以减轻CPU或GPU中Front End部分中某一个的负担&#xff0c;但是会加重另一个的负担。Skinning是mesh中的顶点根据动画中骨骼的当前位置进行计算&#xff0c;从而让角色摆出正确的姿势。 …

Unity手游开发札记——布料系统原理浅析和在Unity手游中的应用

原文&#xff1a;https://zhuanlan.zhihu.com/p/28644618 0. 前言 项目技术测试结束之后&#xff0c;各种美术效果提升的需求逐渐成为后续开发的重点&#xff0c;角色效果部分的提升目标之一便是在角色选择/展示界面为玩家提供更高的品质感&#xff0c;于是可以提供动态效果的…

行为树(Behavior Tree)实践(1)– 基本概念

原文&#xff1a;http://www.aisharing.com/archives/90 行为树&#xff08;Behavior Tree&#xff09;实践&#xff08;1&#xff09;– 基本概念 自从开博以来&#xff0c;每天都会关心一下博客的访问情况&#xff0c;看到一些朋友的订阅或者访问&#xff0c;不胜欣喜&…

Unity 2017 Game Optimization 读书笔记 Dynamic Graphics (5) Shader优化

Shader optimization Fill Rate和 Memory Bandwidth开销最大的地方就是Fragment Shader。开销多大取决于Fragment Shader的复杂程度&#xff1a;多少纹理需要采样&#xff0c;多少数学计算函数需要使用等等。GPU的并行特性意味着在线程中如果任何地方存在瓶颈&#xff0c;都会…

Unity 2017 Game Optimization 读书笔记 Dynamic Graphics (6)

1. Use less texture data 这条优化技巧非常直接&#xff0c;减少texture的数据量&#xff0c;减少分辨率或者降低位数&#xff0c;虽然可能会降低渲染质量。但是通常使用16-bit textures并不会明显的感觉到渲染效果下降。 MipMap技术可以有效减少VRAM和Texture Cache之间来回…

LeetCode 面试题57 - II(剑指offer) 和为s的连续正数序列

今天毕业五年了&#xff0c;一直忙于工作和享受&#xff0c;自从当年找完工作后就一直没有再刷过题&#xff0c;作为搬砖的码农&#xff0c;觉得还是应该养成长期刷题的习惯坚持下去。之前坚持了每天被一会单词&#xff0c;如今雅思一本也快看完了&#xff0c;从今天开始准备在…

反走样技术相关文章

https://zhuanlan.zhihu.com/p/28800047 https://zhuanlan.zhihu.com/p/57503957 https://zhuanlan.zhihu.com/p/33444125 https://zhuanlan.zhihu.com/p/33444429 走样的原因及其分类 说到走样&#xff0c;首先要说的就是采样。这也算是很多图形学专著中提到反走样相关技…

求n的阶乘的算法框图_单片机常用的14个C语言算法

问&#xff1a;怎么每天看到这种文章&#xff1f;答&#xff1a;只需搜索公众号"51单片机学习网"免费关注算法(Algorithm)&#xff1a;计算机解题的基本思想方法和步骤。算法的描述&#xff1a;是对要解决一个问题或要完成一项任务所采取的方法和步骤的描述&#xff…