百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

来讲讲URP 系列教程

csdh11 2024-12-12 11:19 4 浏览

今天带大家了解下什么是 SRP Batcher 与它的工作原理、如何在 URP 工程中去使用 SRP Batcher 以及针对大家在 URP 学习中所遇到的一些问题的解答。

SRP Batcher 的定义与工作原理

我们来看下定义:SRP Batcher是一个渲染循环,它可以在使用很多相同的 Shader Variant 的材质的场景中,加速你的 CPU 渲染。也就是说:我们不但可以通过使用尽可能少的 Shader Variant 来加速,而且也可以使尽可能多的不同材质来使用相同的 Shader Variant 来实现这一性能提升。


那为什么 SRP Batcher 可以实现加速呢?我们来看下它的工作原理。


通常情况下,在 Unity 中,可以在一帧内的任何时间修改任何材质的属性。但是,这种做法有一些缺点。例如,DrawCall 使用新材质时,要执行许多工作。因为场景中的材质越多,Unity 必须用于设置 GPU 数据的 CPU 的工作也就越多。


解决此问题的传统方法是减少 DrawCall 的数量以优化 CPU 渲染成本,因为 Unity 在发出 DrawCall 之前必须进行很多设置。实际的 CPU 成本便来自这些设置,而不是来自 GPU DrawCall 本身(DrawCall 只是 Unity 需要推送到 GPU 命令缓冲区的少量字节)。


而我们的 SRP Batcher 通过批处理一系列 Bind 和 Draw GPU 命令来减少 DrawCall 之间的 GPU 设置的工作量。也就是之前一堆绑定和绘制的 GPU 命令,我们可以使用批处理减少绘制调用之间的 GPU 设置。


Bind和Draw命令的批处理可以减少绘制调用之间的GPU设置

我们可以在 XCode 抓取一帧的数据上也可以明显的看到,如下图所示左边为未开启 SRP Batcher,右边为开启 SRP Batcher;可以看到开启 SRP Batcher 后对比开启前绘制调用之间的 GPU 设置明显的减少。



如何在 URP 工程中使用 SRP Batcher


要使用 SRP Batcher,项目必须使用可编程渲染管线。可编程渲染管线可以是:


通用渲染管线 (URP)

高清渲染管线 (HDRP)

自定义 SRP


因为本篇文章主题是 URP 系列教程,所以接下来我们就手把手带大家一起学习如何在 URP 中使用 SRP Batcher。还是跟往常一样,首先得有自己的 URP 工程。

01 新建 URP 工程

02 创建并设置 URP Assets

在 URP 工程 Assets 目录下 Create > Rendering > Universal Render Pipeline > Pipeline Asset。


然后点击 Edit > Project Settings > Graphics,将这里的 Pipeline Settings 设置为我们已经创建好的 URP Assets。

03 在 URP 中激活 SRP Batcher

点击我们创建并设置好的 URP Assets,你会在 Inspector 面板中 Advanced 选项,展开发现 SRP Batcher 选项,点击勾选(默认已经勾选)。

04 URP Shader 兼容性


不是所有的对象都可以用 SRP Batcher 来渲染,对于渲染对象是有条件限制的。这个对象必须是 mesh 或者 Skinned Mesh,而不能是个 particle。Shader 也必须与 SRP Batcher 兼容,它封装了 URP 中的所有 lit 和 unlit Shader(除了这些 Shader 的粒子版本)。我们可以在 Inspector 中查看 Shader 的兼容性。


05 如何使 Shader 与 SRP 匹配

根据手册可知,要想匹配是有条件的

所有的 Material 属性都要在一个名为 UnityPerMaterial 的 CBUFFER 中声明。

Shader 中所有的内置属性例如unity_ObjectToWorld,unity_WorldTransformParams等,都要在一个名为 UnityPerDraw 的 CBUFFER 中声明。


也就是 Properties 中的参数在声明时,要被包含在了一个这样的语法中:

举个栗子:


当然即使在使用不兼容的对象时,Unity 也会正确渲染场景。这是因为兼容对象使用 SRP Batcher 代码路径,而其他对象则使用标准 SRP 代码路径。


其实到这里,如何在 URP 工程中使用 SRP Batcher 就已经讲完了。但是关于 SRP Batcher 的故事还没有结束。有一位网友在 URP 学习交流群中问了一个问题,我在 SRP Batcher Demo 制作过程中也遇到了同样的问题:URP 在开启 SRP Batcher 后,我们的统计面板会有一些奇怪的变化:比如开启前后 Batches 没有变化、Saved by batching 变成了0、Shadow Casters 有时候也会为负数等?


答案是这里有可能是显示的问题。目前我们的统计面板只能显示默认渲染管线中的这些数据,它“不理解” URP 默认使用的 SRP Batcher。统计面板只能够简单地显示一些数据,我们该如何对 SRP Batcher 进行数据分析呢?这就是我们接下来要讨论的问题。


对 SRP Batcher 进行数据分析


在这里我将为大家演示两种对 SRP Batcher 开启前后进行数据分析的手段,第一个是使用 Frame Debugger 对 SRP Batcher 进行数据分析,第二个是添加 SRPBatcherProfiler.cs 脚本对 SRP Batcher 数据进行分析。我们一起来看一下具体步骤。

使用 Frame Debugger 对 SRP Batcher

进行数据分析

我们可以使用 Frame Debugger 来对 SRP Batcher 时的数据和程序进行分析或者调试。


01 打开帧调试器窗口,选择下拉菜单:Windows > Analysis > Frame Debugger


02 通过选择 Enable 启用 Frame Debugger


03 我们来实际的测试下。我们新建一个 URP 工程,创建并分配好了 URP Assets。


首先我们先通过 Create > Shader > lit Shader 创建一个简单的 Lit Shader。接着我们创建两个 Material,分别命名为 Cube_Drywall_Lit_v1,Cube_Drywall_Lit_v2。这两个 Material 都使用我们刚刚创建好的 Lit Shader,并分别引用两种的 Texture V1、V2。

04 然后我们创建 100 个 Cube,然后分别引用上面我们创建好的材质 Cube_Drywall_Lit_v1 与 Cube_Drywall_Lit_v2。



05 我们先尝试关闭下我们的 SRP Batcher,接着我们启用 Frame Debugger 看看数据:我们发现 100 Cube 产生了 100 个 DC !



06 接着我们尝试打开 SRP Batcher(这里的 URP Assets 是默认使用的,我没有做修改),看看数据:哦吼,直接由 100 降到了 1!



但是这里值得注意的是:这不代表只使用了一个 DrawCall 来显示了这些内容,而是对它们进行了序列上的优化。DrawCall 的数量还是 100 没有变化,我们只是提高了他的效率。



添加 SRPBatcherProfiler.cs 脚本对 SRP Batcher 进行数据分析


01 在你的 URP 场景中创建一个空的 GameObject(这里我将其命名为 Profiler);



02 将 SRP Batcher 模板中的 SRPBatcherProfiler.csC# 脚本(详情请见文末参考资料[4])添加给 Profiler。运行这个脚本:会在场景中出现 SRP Batcher 叠加层,我们就可以找到有关 SRP Batcher 的一些详细信息。



03 SRP Batcher 叠加层中的时间量度以毫秒(ms)为单位,显示 CPU 在 Unity SRP 渲染循环中花费了多少时间。注意:这里的时间为一帧内调用的所有 RenderLoop.Draw 和 Shadows.Draw 标记的累积时间。我们来过下:

CPU Rendering time


指示 SRP 循环在 CPU 中花费的总的累计时间量,而不管使用的是哪种多线程模式,例如单线程,在这里,我们可以最大程度地看到 SRP Batcher 的效果。要查看批处理程序的优化,请尝试将其打开和关闭以查看 CPU 使用率的差异。在此的示例总计为 0.90 毫秒。RT idle:指示 SRP 在渲染线程中占用的空闲时间。在此示例中,渲染线程空闲了 0.03 毫秒。

SRP Batcher code path (flushes)


指示我们的游戏花费在 SRP Batcher 代码路径中的时间。这分为游戏渲染所有对象(shadow passes除外)(0.29ms)和阴影(0.61ms)所花费的时间。如果“阴影”数量很高,请尝试减少“场景”中的阴影投射灯数量,或者在“渲染管线资源”中选择较低的级联数量。flushes 数字表示 Unity 刷新场景的次数,因为它遇到了新的 Shader Variant(在此示例中:89)。较少数量的 flushes 总是更好的,因为这意味着这帧中的着色器变体数量较少。


Standard code path (flushes)


指示 Unity 花费在渲染 SRP Batcher 不兼容的对象(例如粒子)上的时间。


我们看看另外一个例子如下,SRP Batcher 在 0.80 毫秒内刷新了 81 个 Objects:shadow passes 为 0.09 毫秒,所有其他 pass 为 0.71 毫秒。



Global Main Loop: (FPS)


指示全局主循环时间(以毫秒为单位),以及对应的帧率(FPS)。在这里如果您看到 FPS 增加了 20,这不一定意味着您已经优化了场景。要查看 SRP Batcher 是否优化了场景渲染,我们将 SRP Batcher 切换为“开”和“关”,然后在“CPU Rendering Time”下比较数字。

转载声明:作品来源于网络,不作任何商业用途

相关推荐

Micheal Nielsen's神经网络学习之二

依然是跟着MichaelNielsen的神经网络学习,基于前一篇的学习,已经大概明白了神经网络的基本结构和BP算法,也能通过神经网络训练数字识别功能,之后我试验了一下使用神经网络训练之前的文本分类,...

CocoaPods + XCTest进行单元测试 c单元测试工具

在使用XCTest进行单元测试时,我们经常会遇到一些CocoaPods中的开源框架的调用,比如“Realm”或“Alamofire”在测试的时候,如果配置不当,会导致“frameworknotfo...

Java基础知识回顾第四篇 java基础讲解

1、&和&&的区别作为逻辑运算符:&(不管左边是什么,右边都参与运算),&&(如果左边为false,右边则不参与运算,短路)另外&可作为位运算符...

项目中的流程及类似业务的设计模式总结

说到业务流程,可能是我做过的项目中涉及业务最多的一个方面了。除了在流程设计之外,在一些考核系统、产业审批、还有很多地方,都用到相似的设计思路,在此一并总结一下。再说到模式,并不是因为流行才用这个词,而...

联想三款显示器首批获得 Eyesafe Certified 2.0 认证

IT之家7月31日消息,据外媒报道,三款全新联想显示器是全球首批满足EyesafeCertified2.0的设备。据报道,联想获得EyesafeCertified2.0认证的显...

maven的生命周期,插件介绍(二) 一个典型的maven构建生命周期

1.maven生命周期一个完整的项目构建过程通常包括清理、编译、测试、打包、集成测试、验证、部署等步骤,Maven从中抽取了一套完善的、易扩展的生命周期。Maven的生命周期是抽象的,其中的具体任务都...

多线程(3)-基于Object的线程等待与唤醒

概述在使用synchronized进行线程同步中介绍了依赖对象锁定线程,本篇文章介绍如何依赖对象协调线程。同synchronized悲观锁一样,线程本身不能等待与唤醒,也是需要对象才能完成等待与唤醒的...

jquery mobile + 百度地图 + phonegap 写的一个"校园助手"的app

1jquerymobile+百度地图+phonegap写的一个"校园助手"的app,使用的是基于Flat-UI的jQueryMobile,请参考:https://github.com/...

Apache 服务启动不了 apache系统服务启动不了

{我是新手,从未遇到此问题,请各位大大勿喷}事由:今天早上上班突然发现公司网站出现问题。经过排查,发现是Apache出现问题。首先检查配置文件没有出问题后,启动服务发现Apache服务能启动,但是没法...

健康债和技术债都不能欠 公众号: 我是攻城师(woshigcs)

在Solr4.4之后,Solr提供了SolrCloud分布式集群的模式,它带来的主要好处是:(1)大数据量下更高的性能(2)更好扩展性(3)更高的可靠性(4)更简单易用什么时候应该使用Sol...

Eye Experience怎么用?HTC告诉你 eyebeam怎么用

IT之家(www.ithome.com):EyeExperience怎么用?HTC告诉你HTC上周除了发布HTCDesireEYE自拍机和HTCRE管状运动相机之外,还发布了一系列新的智能手机...

Android系统应用隐藏和应用禁止卸载

1、应用隐藏与禁用Android设置中的应用管理器提供了一个功能,就是【应用停用】功能,这是针对某些系统应用的。当应用停用之后,应用的图标会被隐藏,但apk还是存在,不会删除,核心接口就是Packag...

计算机软件技术分享--赠人玫瑰,手遗余香

一、Netty介绍Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。也就是说,Netty...

Gecco爬虫框架的线程和队列模型 爬虫通用框架

简述爬虫在抓取一个页面后一般有两个任务,一个是解析页面内容,一个是将需要继续抓取的url放入队列继续抓取。因此,当爬取的网页很多的情况下,待抓取url的管理也是爬虫框架需要解决的问题。本文主要说的是g...

一点感悟(一) 初识 初读感知的意思

时间过得很快,在IT业已从业了两年多。人这一辈子到底需要什么,在路边看着人来人往,大部分人脸上都是很匆忙。上海真是一个魔都,它有魅力,有底蕴,但是一个外地人在这里扎根置业,真的是举全家之力,还贷3...