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

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函数
测试中该函数也会出现在工作线程中

使用建议

遮挡物:

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

被遮挡物:

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




 

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

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

相关文章

股票量价关系分析

量增价平 量增价平是指成交量增加,股价保持相对平稳的量价关系模型,量的增加可以是资金大量流入引起,也可以是资金大量流出引起,因此这种关系模型需要根据股价所处的位置来具体分析。1、股价处于低位 当股价处于低位,此…

【Linux】用户相关内容

如果命令ll 出现以上信息,UID为具体的数字,代表之前UID为502的用户被删除了。 更改目录或文件所属用户和所属组 在Linux中,创建一个文件时,该文件的拥有者都是创建该文件的用户。 更改所属用户 chown 用户名 文件名/目录名 更…

机器学习实战13-超导体材料的临界温度预测与分析(决策树回归,梯度提升回归,随机森林回归和Bagging回归)

大家好,我是微学AI,今天给大家介绍一下机器学习实战13-超导体材料的临界温度预测与分析(决策树回归,梯度提升回归,随机森林回归和Bagging回归),这几天引爆网络的科技大新闻就是韩国科研团队宣称发现了室温超导材料-LK-99,这种材料…

无涯教程-Lua - Iterators(迭代器)

迭代器是一种构造,使您可以遍历所谓的集合或集合的元素。在Lua中,这些集合通常引用表,这些表用于创建各种数据结构(如数组)。 通用迭代器 通用的 for 迭代器提供集合中每个元素的键值对。下面给出一个简单的示例。 array{"Lua",…

思科单臂路由、lacp链路聚合、NAT实验

实验拓扑图: 实验目的: 如图所示配置相应IP地址和VLAN,并通过在AR1上配置单臂路由,实现VLAN10和VLAN20的主机能够在VLAN间通信;在SW1和SW2的三条链路实施链路聚合,使用静态LACP模式,使一条链…

2023年第四届“华数杯”数学建模思路 - 案例:FPTree-频繁模式树算法

## 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法,就是频繁模式树算法,他与Apriori算法一样也是用来挖掘频繁项集的&#xff0c…

小程序学习(四):WXML模板语法

WXML模板语法-数据绑定 1.数据绑定的基本原则 ①在data中定义数据 ②在WXML中使用数据 2.动态绑定属性 WXML模板语法-事件绑定 3.什么是事件 4.小程序中常用的事件 5.事件对象的属性列表 6.target和currentTarget的区别 7.bindtap的语法格式 8.在事件处理函数中为data中的数据…

【NLP概念源和流】 06-编码器-解码器模型(6/20 部分)

一、说明 在机器翻译等任务中,我们必须从一系列输入词映射到一系列输出词。读者必须注意,这与“序列标记”不同,在“序列标记”中,该任务是将序列中的每个单词映射到预定义的类,如词性或命名实体任务。 作者生成 在上面的

IO进程线程第五天(8.2)进程函数+XMind(守护进程(幽灵进程),输出一个时钟,终端输入quit时退出时钟)

1.守护进程&#xff08;幽灵进程&#xff09; #include<stdio.h> #include<head.h> int main(int argc, const char *argv[]) {pid_t cpid fork();if(0cpid){ //创建新的会话pid_t sidsetsid();printf("sid%d\n",sid);//修改运行目录为不可卸载的文件…

虚拟机中Linux的IP地址配置详解

目录 第一章、虚拟机中Linux的IP地址配置详解1.1&#xff09;什么是IP地址1.2&#xff09;如何查看自己电脑ip地址1.3&#xff09;虚拟机NAT模式中Linux的IP地址设置有什么要求 第二章、使用Linux中的编辑命令进行网卡信息文件的配置 友情提醒 先看文章目录&#xff0c;大致了…

swagger相关问题

swagger相关问题 swagger版本为&#xff1a; <dependency><groupId>com.github.xiaoymin</groupId><artifactId>swagger-bootstrap-ui</artifactId><version>1.9.6</version> </dependency> <dependency><groupId&…

解决ComposerStaticInit类重复加载问题

Tp5中composer安装phpoffice后报错 Cannot declare class Composer\Autoload\ComposerStaticInit6c9266e89aa536667bf36f59ad8e6e6b, because the name is already in use 错误原因: 使用ThinkPHP5框架的项目&#xff0c;在引用某些包的时候&#xff0c;可能会通过其它包&…

leetcode(力扣)剑指 Offer 16. 数值的整数次方 (快速幂)

文章目录 题目描述思路分析完整代码 题目描述 实现 pow(x, n) &#xff0c;即计算 x 的 n 次幂函数&#xff08;即&#xff0c;xn&#xff09;。不得使用库函数&#xff0c;同时不需要考虑大数问题。 示例 1&#xff1a; 输入&#xff1a;x 2.00000, n 10 输出&#xff1a;10…

idea数据库快速上手-库操作与表结构和数据操作

引言 对数据库的操作无非就是执行SQL语句&#xff0c;要想熟练操作数据库&#xff0c;就要熟练运用SQL语句。 一&#xff0c;数据库操作 展示当前服务器内的数据库 -- 展示服务器内的数据库 show databases; show schemas; 执行结果&#xff1a; 创建数据库&#xff1a; --…

不同局域网下使用Python自带HTTP服务进行文件共享「端口映射」

文章目录 1. 前言2. 视频教程3. 本地文件服务器搭建3.1 python的安装和设置3.2 cpolar的安装和注册 4. 本地文件服务器的发布4.1 Cpolar云端设置4.2 Cpolar本地设置 5. 公网访问测试6. 结语 1. 前言 数据共享作为和连接作为互联网的基础应用&#xff0c;不仅在商业和办公场景有…

刷题DAY15

第一题 给定一个数组arr 求子数组最大累加和 最暴力的 枚举每一个子数组 出结果 优化解 用一个cur指针保存累加和 每次cur变大 就用它更新max 如果cur累加到0以下 回复成0 假设答案法 假设我们最大的子数组是i 到 j位置上的 那么这个i 到j 之间 必不存在一个k使i...k累加和…

开源元数据管理平台Datahub最新版本0.10.5——安装部署手册(附离线安装包)

大家好&#xff0c;我是独孤风。 开源元数据管理平台Datahub近期得到了飞速的发展。已经更新到了0.10.5的版本&#xff0c;来咨询我的小伙伴也越来越多&#xff0c;特别是安装过程有很多问题。本文经过和群里大伙伴的共同讨论&#xff0c;总结出安装部署Datahub最新版本的部署手…

Java电子招投标采购系统源码-适合于招标代理、政府采购、企业采购、等业务的企业 tbms

​ 功能描述 1、门户管理&#xff1a;所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含&#xff1a;招标公告、非招标公告、系统通知、政策法规。 2、立项管理&#xff1a;企业用户可对需要采购的项目进行立项申请&#xff0c;并提交审批&#xff0c;查…

14:00面试,14:06就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到5月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%,…

2023年第四届“华数杯”数学建模思路 - 案例:最短时间生产计划安排

文章目录 0 赛题思路1 模型描述2 实例2.1 问题描述2.2 数学模型2.2.1 模型流程2.2.2 符号约定2.2.3 求解模型 2.3 相关代码2.4 模型求解结果 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; 最短时间生产计划模型 该模型出现在好几个竞赛赛题上&#x…