| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 游戏开发 -> Unity 2019 新特性在次时代手游 《黑暗之潮》中的应用经验及技术分享【URP学习笔记之一】 -> 正文阅读 |
|
[游戏开发]Unity 2019 新特性在次时代手游 《黑暗之潮》中的应用经验及技术分享【URP学习笔记之一】 |
目录 2.使用多SetPass的情况会打断合批,使得Draw居高不下。 视频地址:[Unity 活动]-游戏专场|Unity 2019 新特性在次时代手游 《黑暗之潮》中的应用经验及技术分享 ?渲染管线的选择林大是这样描述道:“选择URP的理由,使用移动平台的PBR渲染管线,非PBR的东西也可以拿来渲染。非侵入修改可实现管线自定义,可实现功能定制。全部C#源码,渲染过程可见,可控。源码结构清晰,便于扩展和自定义。 比内置管线性能更好。” 这场分享看下来,基于Shader变种的SPR Batcher,控制Blit操作的使用时机,使用单Pass ColorTexture替代GrabPass,优化LoadStore操作…… 优化后的带宽和使用效率,可以甩内置管线几条街,嗯…… 说着说着就激动了。 1.透明物体容易出现渲染错误透明物体容易出现渲染错误,下面两个图是半透明焰光的示范,可以明显的观察到上图的焰光并没有覆盖到地表上。 如下图,图左为错误结果,图右为正常结果。 ? 在内置管线中的解决方案大都是修改对应Shader的Renderqueue来规避,这种情况下一般是需要引入新的Shade,即使是新增了Shader也同样是会面对同样的问题,随着项目的体量越来越大,Shader越来越多,这种问题的处理,应该会很棘手。或者直接就抛弃掉这种效果,所以说整体效率的内置管线在处理这种业务逻辑的时候,多少有些差强人意。 2.使用多Pass的情况会打断合批,使得Draw居高不下。内置管线的一些效果只能通过Shader Pass实现,如角色增加描边效果,一般都会需要增加额外的Pass去处理。 如下图,虽然Object1和Object2虽然使用了相同的Pass,但两者的Pass操作不能进行合批。 绘制2个物体,每个物体相同的3个Pass,需要6次SetPass操作(Object1,Pass1也是需要一次SetPass),Draw Call的次数也水涨船高,且切换渲染状态是一个高消耗的操作,在这种多Pass物体存在比较多的情况下,势必会造成DrawCall和性能消耗居高不下的局面。 通过可编程渲染管线,可以针对解决上述问题做出一个很好的优化处理。 一次性将使用相同Pass的物体渲染绘制,可以很好的降低切换渲染状态/SetPass操作的数量,在这里我的理解是通过牺牲带宽或者牺牲内存的方式,来换取一个比较少的SetPass操作,以达到一个好的运行状态。 在上图中绘制3个物体,2个Pass,需要执行2次SetPass,相比于内置管线的渲染流程,这种渲染流程下的Draw Call、SetPass、合批操作要高效的多。 3.Blit操作不能自定义开启关闭移动端来说,CPU与GPU带宽有限,Blit操作会带来很多的带宽开销,所以,合理管控Blit操作是一个很好的的优化方案。 内置管线为了兼容性,会在渲染中添加Blit操作,且无法关闭。全屏Blit操作对于移动平台来说开销较大,而在确定的渲染管线中,可以明确知道Blit是否必须,不少情况可以省去。 URP的默认渲染管线先渲染主光源光影效果,再渲染副光源光影效果,把场景所有物体的深度渲染到一张RT上,绘制所有不透明物体,绘制天空盒,把当前的渲染结果会知道RT上做后效的时候使用,所有透明物体的绘制,全屏后效处理,绘制UI,把所有的绘制结果进行Blit操作,然后写到屏幕缓冲区当中。 在《黑暗之潮》的一些应用1.平面阴影不需要额外渲染ShadowMap,也不需要因为使用ShadowMap,也不需要额外的进行采样操作,所以对性能的提升还是比较强的。 2.沙盘地图描边一般的情况下,描边的实现方案一般是法线往外扩(传统描边),但这种对方法在边界比较复杂的情况下,阴影会很难处理,或者说处理的差强人意。 黑暗之潮的做法是,先将地块用纯色绘制出来,然后降采样降低分辨率,接着进行模糊操作,然后再升采样升分辨率,最后地图区域设置透明度。 这样做的好处就是利用较小的带宽消耗,来达到一个比较好的阴影、透明度的过渡。 使用URP自定义组件可以实现的一些效果1.单独针对某一物体设置FOV参数(重载摄像机的变换矩阵) 2.透贴(透明)效果可以通过延后其渲染时机,一般情况下是放在DepthPrepass之前。 3.在任意时间点执行渲染操作。 4.手动调用CommandBuffer底层接口 5.复用已经实现的各种Pass 6.省掉FinalBlitPass操作 后效不可避免的会进行全屏Blit操作,默认情况下会在渲染UI后,使用FinalBlit Pass,将结果复制到FrameBuffer,可以将上述的两个过程进行合并,只进行一次Blit操作。在《黑暗之潮》中给定的方案是利用后效的Blit操作直接讲结果复制到FrameBuffer,并直接在FrameBuffer上进行UI绘制,在省一次Blit基础上还能实现3D场景与UI使用不用的分辨率渲染。 7.可以控制切换RT时RenderBuffer的LoadStore操作。 在内置管线中,渲染的计算结果会先写到片上内存,然后GPU真正绘制的时候,再从片上内存加载到帧缓冲区。这种情况下,有的RT只是为了缓存信息,并不参与GPU的绘制,所以在这种情况下,LoadStore就变得不必要。通过控制LoadStore操作,可以有效地缓解GPU和CPU的带宽压力。 URP的性能优势单Pass实时光照 切换RT可自定义LoadStore操作,节省带宽。 去掉不必要的Blit操作。 SRP Batcher。 单Pass ColorTexture替代GrabPass。GrabPass真·全屏抓取,不会降分辨率的抓取。还有一个问题就是,单次渲染帧中GrabPass不知道会被调用多少次,所以会不可避免的造成一定程度上的性能浪费,尤其是对于移动平台。 SRP Batcher与传统合批Dynamic Batching要求苛刻,且CPU开销大。 Statci Batching对动态物体无效,且内存占用巨大,对LOD不友好。 GPU Instancing对Mesh和Material均一直的情况下生效。 Draw Call开销最大的就是SetPassCall。 通过ConstantBuffer保存PerMaterial/perDraw数据,实现Shader变种级别的合并。 林大有提到中配数据中的32w三角面400dc,已经是内置管线项目的高端机型所达到的效果了,听到这里我都惊呆了,这个SRP Batcher好强啊。 QA环节一些不容忽视的补充StaticBatching 选择面比较小的,同一物体重复次数不多的情况下,最通用的就是SRPBatching 关于变体爆炸,通过变种收集自己用的变种,告诉Unity自己使用的变种,一般的项目最多有200-300个变种。 描边一般是在顶点着色器里面使用法线外扩的方式。 ASE代替ShaderGrap是可以的 SPRBatch切换状态也会带来影响,只是对DrawCall平均调用做了一个优化。 国内大部分机型都支持OpenGl ES 3.0 所以对于ConstantBuffer指令的使用,在国内基本上是没问题的。 URP效率比内置高的情况,一般是两种情况,一种是管线设置不合理,一种就是UnityBug。 ? |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年3日历 | -2025/3/14 20:15:28- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |