Unity 性能优化五:渲染模块压力

2023-11-06

CPU压力

Batching

在GPU渲染前,CPU会把数据按batch发送给GPU,每发送一次,都是一个drawcall,GPU在渲染每个batch的时候,会切换渲染状态,这里的渲染状态指的是:影响对象在屏幕上的外观的渲染属性或材质,比如:材质球,贴如,颜色,渲染模式(透明、半透明)等

unity中的合批方式:

优先级:
SRP Batcher / Static Batching
GPU Instancing
Dynamic Batching

Draw Call Batching的使用条件
1. 支持Mesh Renderers、Trail Renderers、Line Renderers、Particle Systems
和Sprite Renderers,且只能批量处理相同类型的Renderer,不支持skin renderers

2. 需要使用相同的材质,因此在脚本中要使用Renderer.sharedMaterial而不是
Render.material,后者生成的是材质的副本,会打断合批
3. 使用MaterialPropertyBlock也会打断合批,不过它还是比使用多个材质要快
4. 透明物体的渲染严格按照先后顺序执行,合批很容易被打断
5. 尽量不要使用负的缩放值
 

StaticBatching:

static batching 的目的不是减少drawcall ,而是减少渲染状态的改变,因为在渲染之前,要设置该物体的各种渲染属性,如果是同一个批次,只设置一次就好了。

static batching 之所以不会减少drawcall,是因为静态合批的物体是可以被裁剪的,它只是合并了顶点数组,但是顶点索引还是单独的,这样就可以根据索引值来决定绘制哪些submesh,比如10个网格 static batch 成了一个网格,但是第5个网格没在视锥体内,则有2个drawcall,第1-4个submesh,第6-10个submesh,第5个是被裁剪了,虽然是2个drawcall,但是渲染状态只设置1次

如果不静态合批,虽然这10个mesh 的材质球、贴图都是一样的,也会分10个drawcall 去绘制,也就是10个batch ,要设置10次渲染状态。


细节补充:
1. 在编辑器中静态合批,Unity不会使用任何运行时的CPU资源来生成网格数据
2. 运行时进行静态合批会有一次较高的CPU峰值,可能会造/成一次卡顿
3. 完成静态合批后,对象成为一个整体,且为静态,无法修改Transform属性
4. 运行时可以对合批后的根对象staticBatchRoot进行Transfform属性的修改,
5. 不过运行时合批的对象需要开启Read/Write选项
 

手动网格合并

手动合并网格,和静态合批差不多,但是它不能裁剪submesh,如果视野中只有单个submesh,也会绘制整个mesh

Dynamic Batching

它在Unity中有两种类型,一种针对网格,一种针对动态生成的几何体,比如粒子系统

动态合批的目的是为了减少CPU的耗时,但是合批本身就消耗CPU,所以它里合批的条件比较严格

GPU Instance

原理:
Unity对于所有符合要求的对象,将其位置、缩放、uv偏移、lightmappindex等相关信息一次性存到Constant Buffer常量缓冲区中,当一个对象作为实例进入渲染流程时,会根据传入的Instance ID来从显存中取出对应的信息,用于后续的渲染阶段,不用每次都发送数据到GPU,以此实现优化的效

使用方法
1. 在材质的Inspector面板中勾选Enable Instancing的选项
2. 使用Graphics.DrawMeshInstanced或Graphics.DrawMeshInstancedirdirect 手动调用GPU instance

MaterialPropertyBlock

使用MaterialPropertyBlock设置随机颜色,不会打断合批,如果直接用material.setcolor 则会打断合批,因为那是一个单独的材质球,它和GPU Instance 最适配,和SRP Batcher最不适配

缺点:优先级比较低、提交一次drawcall 耗时比平常要多一点

优点:

  • 相比静态合批不会带来额外的内存压力
  • 相比动态合批没有严格的顶点限制
  • 与MaterialPropertyBlock很适配,不会打断合批

适用场景:
需要画大批相同Mesh的场景,如草海、树林之类的

SRP Batcher

对于使用相同的着色器变体的材质,也就是对shader合批,即使材质球不一致,只要shader一致,就可以,当项目切换到SRP管线后,通过UniformBuffer传递信息,开启SRP Batcher后,会预先生成Uniform Buffer,批量传递信息,SRP Batcher以Shader为单位进行合批,可以有效降SetPassCall(设置渲染状态)的数目,用于CPU性能优化
 

原理:

对于未开启SPR Batcher的渲染流程是:每一个物体的属性都会在GPU上存在一个CBuffer,这里面包括Gameobject 属性,比如transform,material 属性,比如材质,光照贴图等。当其中属性更新时,就要重新设置数据,每增加一个material ,就会设置一遍对应的cbuffer,耗费CPU

开启了之后,流程发生了变化,相同的shader,对于那些不同的属性,比如transform,会生成一个大的buffer,对于相同的属性,比如光照贴图等,每一个都生成一个小的permaterial,当有状态改变时,才会修改该buffer,如果只是修改了transform,只会通过偏移写入相同位置的数据。

而对于新增的material,它的shader没变,则合批就不会变

传统上,人们倾向于减少Draw Call的数量来优化CPU,Draw Call本身只是推入GPU命令缓冲区的一些字节,真正的CPU成本来自于DrawCall之前的许多设置,SRP Batcher不会减少DrawCall的数量,它只是降低了Draw Call之间的设置成本

渲染管线要求:
支持URP、HDRP、SRP,不支持Built-in管线
游戏对象要求:
必须包含一个Mesh或者Skinned Mesh,不能是粒子
不能使用MaterialPropertyBlock
Shader必须兼容SRP Batcher
 

优点:
节省UniformBuffer的写入操作,支持动态物体,支持的范围要比静态合批更广泛,同时内存上的代价会小很多,材质多的情况也适用

适用场景:
Shader重复率高,但是要控制Shader变体的数量
 

四种方法的对比

优先级:
SRP Batcher / Static Batching > GPU Instancing > Dynamic Batching
适用情况:
Static Batching+SRP Batcher:主城,副本建筑
SRP BatcherOnly:种类繁多的植被
GPU Instancing:种类单一的植被
Dynamic Batching:Ul,粒子,Sprite等

Culling

在GPU进行渲染之前,需要CPU传递渲染数据给GPU,因此需要先将一部分不需要进行渲染的对象进行剔除,也就是Culling。Unity引擎原生就支持了视椎体剔除,即将视域体范围外的对象进行剔除,这部分对象的数据就不用传给GPU进行处理。

在Unity中,所有的可视内容都继承自Renderer,比如MeshRenderfer、SpriteRenderer、LineRenderer、SkinnedMesh Renderer、TrailRenderer等在Unity进行渲染的过程中会它们进行筛选,自动执行视锥体剔限的操作

如果场景中激活的相机数量多,那么Cullling的总耗时也相应增高,即使没有用来显示物体,也会执行culling 耗时,函数体现在  Render 线程中的->Camera.Renderer 

CullingGroup

CullingGroup是Unity提供的一个API接口,它本身和Unity自己的Cu系统以及LOD是同一体系,相当于开放了一些Cull底层的功能供用户使用
Unity - Manual: CullingGroup API

Occlusion

基本介绍
摄像机在每一帧中执行剔除操作,这些操作会检查场景中的渲染器,并排除
(剔除)那些不需要绘制的渲染器
默认情况下,摄像机执行视锥体剔除

工作原理
在Unity Editor中生成有关场景的数据,然后在运行时使用该数据确定摄像机可以看到的内容,生成数据的过程称为烘焙.
在对遮挡剔除数据进行烘焙时,Unity将场景划分为多个单元,并生成描述单元内几何体以及相邻单元之间可见性的数据,然后,Unity尽可能合并单元,以减小生成的数据的大小,在运行时,Unity会将这些烘焙的数据加载到内存中,并且对于每个启用了Occlusion Culling属性的摄像机,将会对数据执行查询以确定该摄像机可以看到的内容

在CullSendEvents的子线程下方会出现CullQueryPortalVisibilitylJmbra函数
测试中该函数也会出现在工作线程中

使用建议

遮挡物:

  • 大的遮挡物具有良好的遮挡质量,比如山
  • 组合起来大的遮挡物并不合适,因为遮挡无法累计,如森林
  • 不要有太多的缝隙,如奶酪
  • 建模时要注意避免无意造成的缝隙
  • 尽量不要让相机能进入遮挡物内部,可通过碰撞实现

被遮挡物:

  • 可以将大部分都设置为被遮挡物,便于被剔除
  • 非常大的物体不适合作为被遮挡物,因为它总会被看到,如地形,可以考虑将其分割为多个部分




 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity 性能优化五:渲染模块压力 的相关文章

  • 【Unity】运行时创建曲线(贝塞尔的运用)

    Unity 运行时创建线 贝塞尔的运用 1 实现的目标 在运行状态下创建一条可以使用贝塞尔方法实时编辑的网格曲线 2 原理介绍 2 1 曲线的创建 unity建立网格曲线可以参考 Unity程序化网格体 的实现方法 主要分为顶点 三角面 U
  • Python 的配置文件模块: :1(?)

    我正在使用Python v2 4 profile分析模块numpy脚本 以下条目似乎占据了大部分执行时间 ncalls tottime percall cumtime percall filename lineno function 256
  • 无法使用 gprof(gnu 分析器)累积时间

    我在 Windows 上运行 cygwin 并使用最新版本的 gprof 来分析我的代码 我的问题是 平面配置文件显示我代码中每个函数的时间为零秒 我什至尝试循环函数 尝试了一百万个 for 循环 但 gprof 无法累积任何时间 请帮忙
  • VS2022 | 显示Unreal Engine日志

    VS2022 显示Unreal Engine日志 视图 gt 其他窗口 gt Unreal Engine日志 视图 gt 其他窗口 gt Unreal Engine日志
  • Emacs 诊断:Org 模式速度慢得难以忍受并且经常停止

    我的 Emacs Windows 10 64 位下的 GNU Emacs 25 1 1 x86 64 w64 mingw32 变得异常缓慢且不稳定 尤其是在 Org 模式下 例如可能会暂停 2 秒以上来移动光标 并暂停 3 秒以上来刷新以显
  • 测量 Java 程序内存使用情况的最佳方法?

    我目前正在使用VisualVM 但我遇到的问题是我无法保存它生成的图表 我需要报告一些有关其内存使用情况和运行时间的数据 尽管运行时间很容易获得System nanoTime 我也尝试过NetBeans 分析器但这不是我想要的 因为我不是在
  • 游戏开发常见操作梳理之NPC任务系统

    多数游戏存在任务系统 接下来介绍通过NPC触发任务的游戏制作代码 using System Collections using System Collections Generic using UnityEngine
  • 游戏开发常见操作梳理系列之——玩家信息的显示系统

    在游戏中 有不少游戏在左上角会出现玩家的头像和等级以及血量 这就是玩家的信息显示系统 那么这些是如何制作的呢 接下来我将讲讲代码的操作 其它操作我会在其它笔记中一一说明 敬请期待 信息的显示相当简单就是控制一些UI 然后在其它系统里面填写相
  • 游戏开发常用实践操作之按动任意键触发

    接下来一些笔记会对于一些大大小小的实践操作进行记录 希望对你有所帮助 在游戏中 我们经常会遇到一些按动任意键触发的操作 接下来展示核心代码 以下是对于Unity中的操作 使用的UI是NGUI 对于核心操作没有影响 你可以自己置换 void
  • 游戏开发常见操作系列之敌人系统的开发一(U3D)

    在开发游戏的过程中 我们常常会出现一些敌人攻击我们玩家 并且实现掉血以及死亡的现象 敌人还会源源不断地生成 这是怎么制作的呢 接下来为大家提供方法 其中使用了NGUI 后续会更新其它方法 敬请期待 使用HUDText实现扣血时显示文本 直接
  • 为什么 React devtools Profiler 不向我显示组件属性?

    我开始学习React的优化 并看到一些学习资源 在它们上 我可以在探查器中看到组件道具 但在我的 Profiler 中 我没有看到任何道具 为什么 如何在 Profiler 中查看当前渲染组件的 props A make screensho
  • 如何修改 C 程序以便 gprof 可以分析它?

    当我在我的 C 程序上运行 gprof 时 它说我的程序没有累积时间 并且所有函数调用都显示 0 时间 但是它确实对函数调用进行计数 如何修改我的程序 以便 gprof 能够计算某项运行所需的时间 编译的时候有没有指定 pg http so
  • 当我在分析模式下运行我的应用程序时,它停止响应

    我的 Android 应用程序在长时间运行的会话中遇到一些 OutOfMemory 错误 为了找到原因 我尝试使用 Android Studio Profiler 但它停止工作并在使用后 10 秒内冻结应用程序 这是 Android Stu
  • 使用 Android Profiler 时应用程序不断崩溃

    我的应用程序正在执行一些位置跟踪并在需要时更新数据库 该应用程序已运行 2 天 没有任何问题 现在我尝试使用 Android Profiler Android Studio 3 01 但是 一旦我打开它 它就会运行几秒钟 然后开始使应用程序
  • 开发RESTful应用程序时如何使用Yii2调试器?

    就像在指南中一样 我创建了 RESTful 控制器 UserController namespace app controllers use yii rest ActiveController class UserController ex
  • Android Profiler 未出现在 Android Studio 中

    我想分析我的设备中的内存消耗 但我没有找到Android 分析器Android Studio 中的选项卡如下所示 请问谁能帮我显示这个选项卡 如果你看一下顶部菜单 你会看到个人资料图标单击它 它将启动您的应用程序并附加配置文件 请参阅下面的
  • 如果分析器不是答案,我们还有什么其他选择?

    看完Joshua Bloch的演讲 绩效焦虑 后 我读了他在演讲中建议的论文 评估 Java 分析器的准确性 http www plan cs colorado edu klipto mytkowicz pldi10 pdf 引用结论 我们
  • C#/.NET 分析器应具有哪些功能?

    这可能是一则边缘广告 更不用说主观了 但这个问题是诚实的 在过去的两个月里 我一直在为 NET 开发一个新的开源分析器 称为 SlimTune Profiler http code google com p slimtune http co
  • 如何禁用 Symfony 2 分析器栏?

    它没有添加任何内容 而且使页面变慢 我希望它消失 别问 网站上几乎没有关于探查器的信息 应用程序配置中也没有任何内容 这个设置是在app config config dev yml web profiler toolbar true int
  • 在 Windows 10 家庭版上运行性能配置文件

    我正在尝试在 Windows 10 上运行 IIS Express 的 Visual Studio 2017 探查器 但我遇到了一些麻烦 当我尝试安装所有必需的 IIS 组件时 我注意到我缺少一些组件 因为我运行的是 Windows 10

随机推荐

  • 《人工智能狂潮》读后感——什么是人工智能?(一)

    从本专栏开始 作者正式研究Python深度学习 神经网络及人工智能相关知识 前一篇文章详细讲解了无监督学习Autoencoder的原理知识 然后用MNIST手写数字案例进行对比实验及聚类分析 本篇文章将分享 人工智能狂潮 书籍内容 包括人工
  • 【一题多解】插入回文串——典型的动态规划区间模型

    插入回文串 典型的动态规划区间模型 题目 给定一个长度为n n lt 1000 的字符串A 求插入最少多少个字符使得它变成一个回文串 之前我做的DP的问题 大多都是二维的或者一维的 今天就讲下这道典型的一维区间模型 附上之前写过的二维一维D
  • 二叉树叶子节点数和度为2的节点数

    我们设度为0 1 2的节点分别为n0 n1 n2个 那么节点总数n n0 n1 n2 然而边数b n 1 并且b n1 2 n2 n 1 n0 n1 n2 1 由此式我们可以推出n0 n2 1 也就是说叶子节点要比度为二的节点多一个 转载于
  • 总结 运行Scrapy项目结果出错:KeyError: ‘Spider not found:

    1 命令行窗口的当前路径不在scrapy工程目录中 需要先进入scrapy工程目录 不一定要工程根目录 下一级子目录也可以 2 执行命令 scrapy crawl fileName 时 不要加 py后缀 本人就是加了后缀 一直错误 正确 s
  • ChromeOS 体验

    概述 作为一名开发人员 一直关注各种桌面级 移动级操作系统的进展 其中就包含 ChromeOS 对于一个开发者 客户端 嵌入式 硬件开发者除外 而言 对于操作系统的要求如下 流畅 稳定而现代化的系统 UI 完整的 Linux 环境 好用的浏
  • C#get和set

    这里写目录标题 为什么要使用get和set 使用get访问私有变量 使用set和get定义一个索引器 为什么要使用get和set 因为在代码中存在着私有的值 我们不能在它的私有域外调用这些私有值 若要访问这些私有值 则需要使用get和set
  • Python,OpenCV图像金字塔cv2.pyrUp(), cv2.pyrDown()

    Python OpenCV图像金字塔cv2 pyrUp cv2 pyrDown 1 效果图 2 原理 2 1 什么是图像金字塔 2 2 金字塔分类 2 3 应用 3 源码 参考 这篇博客将介绍图像金字塔的理论 及用图像金字塔cv2 pyrU
  • vscode快捷键创建多个html标签

    vscode快捷键创建多个html标签 vscode中输入命令 按下Tab键 Tab键 没反应解决办法 参考地址 https blog csdn net xingyun piaofu article details 131879072 sp
  • 前端福利:使用Wallpaper Engine让自己的桌面炫酷起来

    Wallpaper Engine 是一款Steam上的特别特别炫酷的壁纸定制软件 它可以对你的桌面进行定制 可以使用视频 动画 网页等形式来替换壁纸 注意到没 关键是可以使用Html格式的文件作为桌面 前端福利啊有木有 首先 先先下载软件下
  • QT结合Mupdf实现预览pdf

    要在Qt中结合MuPDF库预览PDF文件 你可以按照以下步骤进行操作 1 下载并安装MuPDF库 首先 你需要从MuPDF的官方网站或代码托管网站上下载MuPDF库的源代码 并按照文档中的说明进行安装 确保你已经安装了所有必需的依赖项 2
  • 因果推断综述-A Survey on Causal Inference

    最近读到一篇讲述很全面的综述文献 A Survey on Causal Inference 对于接触因果推断不久的同学而言是特别详细的介绍和科普 文献很长 我会分成几部分介绍 目录 摘要 第一部分 简介 第二部分 因果推断基础知识 第三部分
  • java(有关类成员变量的访问权限)

    private public protected 默认不写 firendly 1 Class类的访问权限 public 可以供所有的类访问 默认 默认可以称为friendly但是 java语言中是没有friendly这个修饰符的 这样称呼应
  • Linux 编写定时任务

    1 先进入根目录 mkdir p home wangwenjun scripts cd home wangwenjun scripts 2 编写第一个shell文件 test sh vim test sh bin sh now date Y
  • Windows下Git-preview中文乱码的解决方法

    在Windows下安装Git preview 1 7 4后 使用中发现许多的乱码问题 感觉甚是不便 这是因为Git是在linux下开发的管理软件 而linux的编码方式是基于UTF 8的 所以移植到Windows之后难免会存在编码方式不同的
  • android wear 微信语音,moto 360手表语音回复微信教程

    moto360智能手表是一款搭载android系统的智能手表 目前微信已经添加了对智能手表的支持 不过很多玩家对于怎么使用moto 360语音回复微信还不是很清楚 下面小编就为大家分享一下moto 360语音回复微信教程 moto 360语
  • 最大权闭合子图(最小割)

    最大权闭合子图 最大流最小割 参考资料 1 最大权闭合子图 权闭合子图 存在一个图的子图 使得子图中的所有点出度指向的点依旧在这个子图内 则此子图是闭合子图 在这个图中有8个闭合子图 3 4 2 4 3 4 1 3 4 2 3 4 1 2
  • Qt绘图QGraphicsView、QGraphicsScene、QGraphicsItem简述

    Qt绘图中 QGraphicsView QGraphicsScene QGraphicsItem三者之间密不可分 以下简单介绍三者之间关系 三者之间关系 如同绘画的过程 Qt绘图中 QGraphicsView的作用相当于画板 QGraphi
  • linux 使用笔记

    1 查看使用的所有端口 netstat ntlp 2 查找文件路径 locate 文件名 如 find 文件名 如 find home 3 Linux下查看和停止所有java进程 在Linux下查看所有java进程命令 ps ef grep
  • 摄像机跟踪主角第三人称的视角

    using UnityEngine using System Collections public class FollowFarget MonoBehaviour public Transform PlayerTransfrom 定义一个
  • Unity 性能优化五:渲染模块压力

    CPU压力 Batching 在GPU渲染前 CPU会把数据按batch发送给GPU 每发送一次 都是一个drawcall GPU在渲染每个batch的时候 会切换渲染状态 这里的渲染状态指的是 影响对象在屏幕上的外观的渲染属性或材质 比如