unity 性能优化之合批和剔除

news2025/1/4 19:43:14

批次对渲染的性能影响是比较大的,批次过多会导致cpu提交的次数过多,导致每帧渲染时间过长,所以我们需要对其优化,减少Bathches数量和SetPassCall次数。
批次合并的方法有多种,下面一一列出:

手动合批

将相同材质的Mesh,合并为一个新的Mesh,这样一次渲染,最方便调节,虽然现在不怎么使用这种方式。就是有点费手,会增加内存和包体大小,而且会增加LightMap中占有的尺寸,以及重新制作LOD,并且体积过大了会导致LightProbe和ReflectionProbe的变化单一。相关插件:MeshBaker以及教程

静态合批 Static batching:

原理:

在非运行期间,自动计算Mesh合并后的顶点并转换到世界空间坐标系下,构建共享的顶点和索引缓冲区,在运行时将该数据上传到gpu。编辑器运行是在点击运行时编译,打包是会在build时打包在场景中。对于场景,每个静态物体没有实际的合并操作,还是单独的个体,在运行时,我们会发现它使用了一个合并的Mesh。运行时还是按照正常流程对每个物体进行剔除,排序,渲染操作。渲染单个物体时,每个渲染器组件调用Drawcall中仅包含三角形索引的偏移量和范围,因此速度非常快。静态合批不会减少Drawcall,而是减少了SetPassCall和数据提交的次数。简单的理解就是,静态合批只是改变了提交的内容,让多次提交变为了一次,而这些次的提交只是改变成了从那一次提交的内容里面拿数据渲染。

条件:

材质及shader参数要完全一致才能合批。LightMap,LightProbe,ReflectionProbe,多光源都需要一致,LightMap尽量增加尺寸推荐2k,其它的尽量禁掉,或者增大影响范围,共用一个。
合批是在世界空间下,如果使用了对象空间坐标,会出现错误。

优点:

合并操作是自动处理,没有污染,不会更改任何场景内的数据,对象可以单独进行剔除,LOD

缺点:

内存和包体占用增加,特别是大量重复的物体,树,草。每个批次最多包含65000个顶点,超出了会额外合并。

GPU Instancing

原理

GPU Instancing是将一个网格发送到GPU并使用一组变换矩阵和MaterialPropertyBlocks对其进行渲染。
当执行Instance合批时,会收集所有需要的信息(变换矩阵,材质属性块)创建一个按实例ID索引的数组。矩阵是存储的世界空间坐标系数据,如果每帧合批的物体有变动,那么每帧都需要付出性能进行数据重新生成。材质属性块则是用来可以自定义一些单独的属性(per-instance property),但是不支持纹理,需要额外的书写支持。实现方式在shader中需要写入常量缓冲区:

UNITY_INSTANCING_BUFFER_START(Props)
  UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
UNITY_INSTANCING_BUFFER_END(Props)

我们需要将切换的属性写在UNITY_INSTANCING_BUFFER_START和UNITY_INSTANCING_BUFFER_END之间。然后还需要在程序上兼容,可以在调用 DrawMeshInstanced 时通过脚本手动构建,或者使用 MaterialPropertyBlock 在Renderer组件上设置。

几种实现方式

  1. 在材质球面板开启GPU Instance选项
    这种方式也是基本上常用的方式,也是一种自动化的GPU Instancing。勾选以后,即可实现了GPU Instancing合批,重要的是你的Shader一定要支持,unity内置的都支持。
    Unity会根据摄像机当前所见的物体,收集信息动态构件Constant Buffer(常量缓冲区),如果材质上的属性不同,我们还可以在shader上增加额外的一些属性,这些属性需要写在UNITY_INSTANCING_BUFFER中间。
  2. DrwaMeshInstanced
    这个需要使用代码实现控制GPU Instancing,能够一次绘制更多的物体,最多一次绘制1023个,这个主要取决于CBuffer的容量,Constant Buffer的最大容量只有64K。这种实例化方法同脚脚本管理一个持久的常量缓冲区(CBuffer),不会随着摄像机所见物体频繁更改CBuffer。因此能获得更好的cpu和gpu性能,代价就是占用一定的cpu内存。这种方式会绕开unity的渲染框架,因此每个模型无法应用剔除操作和LOD等功能。
  3. DrawMeshInstancedIndirect / DrawMeshInstancedProcedural
    官方文档点击此处,这种方法是通过COmputeBuffer来提供Instance数据,ComputeBuffer其实是StructureBuffer,容量可以比Constant Buffer大很多。因此这种方法可以绘制巨量的Instance。几何Compute Shader能够实现GPU Frustum Culling(GPU视椎体剔除)和Hi-z Occlusion Culing(Hi-z遮挡剔除),缺点是兼容性差,需要ShadingModel 4.5以上,支持Compute Shader 和 Compute Buffer的硬件特性。

实现条件

  1. 需要相同的Mesh
  2. 需要相同的材质
  3. Shader需要支持GPU Instancing

优势

  1. 不会因为物体的增加额外占用大量的内存。
  2. 适用于大量重复的物体,比如树,草,小石头等
  3. 支持per-instance property,自定义单个模型的属性

缺点

  1. 只能支持相同的Mesh
  2. LOD会打断GPU Instancing合批,静态的则不会,因为合并的时候,它已把LOD相关的合并在了一个模型内。

相关插件:GPU Instancer

SRP Batcher

原理

SRP是基于Shader进行的批处理,不需要Mesh和材质相同,它是实现了,减少每种材质切换时的设置也就是减少cpu和gpu之间的交互来实现性能优化。运行逻辑是在启动时,将网格上传到gpu,然后将使用SRP合批的材质主数据放入列表一次上传并在每帧更新时去更新列表中的数据。渲染时会对列表进行偏移获取数据渲染,主要起到了合并SetPassCall的作用。

实现条件

  1. 必须是一个Shader变体,同一个Shader变体,同样的宏,以及同样的队列同样的混合模式,深度检测写入等。
  2. Shader需要支持SRP,正常URP内书写的Shader,首先变量需要写到UnityPerMaterial中:
    在这里插入图片描述
    如果你的shader支持SRP,能够在shader面板上查看到
    在这里插入图片描述

优势

  1. 减少了数据的上传,不用每次都上传网格体
  2. 大大减少了cpu和gpu之间的通信
  3. 支持不同的材质,只要shader变体相同即可
  4. 支持Skining Mesh 骨骼模型

技术选型

  1. 静态物体还是推荐使用静态合批的方式。
  2. 如果大批量的相同材质相同模型的渲染使用GPU Instancing合批
  3. 骨骼模型只能使用SRP
  4. 其它的都使用SRP
  5. 如果材质支持SRP,即使设置了GPU Instancing也不会启作用,可以修改shader让其不支持

剔除

unity内置的剔除模式有:

  1. 视椎体剔除 相机看不到的地方剔除掉
  2. layerCullDistances 可以给不同的层级设置剔除距离
  3. 遮挡剔除 被其它模型遮挡住的模型剔除掉

unity商店不错的插件:

  1. Optimizers
  2. Scene Optimizer
  3. Frustum Culling
  4. Perfect Culling - Occlusion Culling System

同屏面数优化

对于静态模型,同屏面数主要影响GPU耗时
对于骨骼模型,模型面数会影响CPU骨骼动画或者布料模拟的耗时
在不影响游戏质量的情况下,尽可能将面数控制在可接受的最低范围。需要经验丰富模型美术同学在制作环节把关
相关插件:

  1. Poly Few | Mesh Simplifier and Auto LOD Generator
  2. Amplify Impostors
  3. Mesh Combine Studio 2

其它方面

其它我们还需要注意毕竟影响cpu和gpu交互的地方
光照,多Pass,实时阴影,平面反射,实时ReflectionProbe 多相机

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

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

相关文章

CRM系统多少钱一套?盘点主流各大CRM系统价格

阅读本文你将了解:1.CRM定价规则;2.各大CRM系统报价(CRM系统多少钱一套);3.CRM系统费用构成。 一、CRM定价规则 很多企业都寻求使用CRM系统来管理客户关系,从而优化管理流程,提升业绩。 对于企业而言&…

1985-2021年全国31省一二三产业就业人数/各省分产业就业人数数据(无缺失)

1985-2021年全国31省一二三产业就业人数/各省分产业就业人数数据(无缺失) 1、时间:1985-2021年 2、范围:包括全国31省 3、来源:各省NJ、社会统计NJ、人口和就业NJ 4、指标包括:省第一产业就业人数、省第…

Baumer工业相机堡盟相机如何使用PixelTransformation像素转换功能(像素转换功能的使用和优点以及行业应用)(C#)

项目场景 Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具…

2023年,web前端工程师20道Vue面试题及解析

本文章列出了20道关于Vue.js的面试题,包括基础和进阶问题,并提供了问题的答案及解析,以帮助读者更好地准备面试。从指令、生命周期函数到组件间通信和路由等各方面都作了涉及。 1. 什么是Vue.js?它有哪些特点? 答案&…

Git服务器集成(一)

本篇文章旨在分享本人在学习Git时的随笔记🤩 文章目录 Git 远程服务器1、下载 Git 软件(linux版本)2、安装 Git 软件2.1 解压 Git2.2 安装依赖2.3 删除旧版 Git2.4 编译、安装 Git2.5 配置环境变量2.6 建立链接文件2.7 测试安装 3、创建 Git …

使用Selenium控制Chrome浏览器 --工作自动化

使用Selenium控制Chrome浏览器 --工作自动化 背景: 最近朋友在用秒账做帐时,由于销售单量很大,重复录入工作一天一录就近五个小时,寻求帮助,问能不能把这重复劳动减少些,看后分析,使用web自动…

为网站的中文和英文使用不同的字体

CSS为网站的中文和英文使用不同的字体 前言 最近我在搭建个人网站,在这个过程中遇到很多的问题,不过chatGPT3.5帮助了很多,这是我使用的咒语: 我正在搭建一个个人网站,使用python Flask框架,CSS采用Boots…

linux网络设置与维护命令

文章目录 一、linux网络设置与维护命令总结 一、linux网络设置与维护命令 Linux ifconfig命令:配置或显示网络接口信息 Linux netstat命令:显示网络状态 Linux ip命令:执行网络管理任务 Linux ping命令:测试主机间网络连通性 Linux wall命令:发送广播 Linux finger命令:查找并…

ShardingJDBC的实核心流程和商户商家订单的分片实现

一、ShardingJDBC的核心流程 ShardingJDBC的核心流程主要分成六个步骤,分别是:SQL解析->SQL优化->SQL路由->SQL改写->SQL执行->结果归并,流程图如下: 4.1、SQL解析 分为词法解析和语法解析。 先通过词法解析器将SQL拆分为一…

基于ESP32 蓝牙游戏手柄设计

使用 ESP32 并通过 BLE 通信的 DIY 手持游戏手柄 这个项目中使用的东西 硬件组件 esp32 1 ws2812b 6 操纵杆 2 角度按钮 2 按钮 8 18560电池和电池座 2 3路拨动开关 1 TP4056带保…

【从0到1了解Libarchive】带你了解Libarchive Libarchive的用途意义以及成功入门Libarchive

目录 0 如果你还不知道Libarchive是什么请一定要先看一下 1 简介 1.1 为什么实现Libarchive 1.2 到底都有谁在用呢? 1.3 Libarchive都有哪些功能 1.4 我们可以通过这些获取更多信息 1.5 如何贡献 2 Libarchive归档与压缩 3 Libarchive编译 4 Libarchive简…

ApplicationContext 和 BeanFactory 的区别

✏️作者:银河罐头 📋系列专栏:JavaEE 🌲“种一棵树最好的时间是十年前,其次是现在” 目录 ApplicationContext 和 BeanFactory 的区别 ApplicationContext 和 BeanFactory 的区别 那么这 2 种获取 Spring 上下文对象…

搭建electron-vue上

electron-vue 准备工作修改package.jsonappveyor.yml.travis.yml.gitignore.eslintrc.js.eslintignore.babelrcsrc/renderer/main.jssrc/renderer/App.vuesrc/renderer/store/index.jssrc/renderer/store/modules/Counter.jssrc/renderer/store/modules/Counter.jssrc/renderer…

渗透测试 | 目录扫描

0x00 免责声明 本文仅限于学习讨论与技术知识的分享,不得违反当地国家的法律法规。对于传播、利用文章中提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,本文作者不为此承担任何责任,一旦造成后果请自行承担…

BUUCTF ciscn_2019_n_8

小白垃圾做题笔记而已,不建议阅读观看。 看到保护后我………………傻眼了。这保护全看根本无从下手嘛。 看到源程序后我依然有点迷茫。 我是小白,直到看到了大佬的wp,我才有有点头绪。 这里,var[13]里的不能为0 并且里边存储的还…

Java 基础入门篇(六)——— String 类详解

文章目录 一、String 类概述二、String 创建对象的方式2.1 创建对象的两种方式2.2 面试:两种方式的区别 ★2.3 常见面试题 ★ 三、String 类常用方法3.1 字符串内容比较3.2 常用 API:遍历、截取、替换、分割 一、String 类概述 java.lang.String 类代表…

R语言 | 日期和时间的处理

目录 一、日期的设定与使用 1.1 as.Date()函数 1.2 weekdays()函数 1.3 months()函数 1.4 quarters()函数 1.5 Sys.localeconv()函数 1.6 Sys.Date()函数 1.7 再谈seq()函数 1.8 使用不同格式表示日期 二、时间的设定与使用 2.1 Sys.time()函数 2.2 as.POSIXct()函数…

ChatGPT学习企业产品、服务内容、往期方案,处理所输入的客户需求,定制化生成解决方案

该场景对应的关键词库(6个): 企业产品和服务内容、客户需求和参数、营销方案和推广策略、数据处理和模型训练、客户满意度和营销效率、往期营销方案 提问模板: 场景产品问题 模板1: 场景:某家电公司生产的…

【Redis】Redis单线程和多线程

Redis单线程 Redis为什么是单线程 Redis的版本很多,比如3.x、4.x、6.x等,版本不同,架构不同: 3.x版本,最早的版本,单线程4.x版本,严格意义上来说不是单线程,负责处理客户端请求的…

使用Vue+axios+Vuex实现登录后前端数据本地化存储实战

前言 这已经是《Vue + SpringBoot前后端分离项目实战》专栏的前端部分第8篇博客了,服务端部分由天哥(天哥主页)负责,目前专栏目录如下: Vue + SpringBoot前后端分离项目实战 - 前端部分1. 手把手带你做一套毕业设计-征程开启2. 我应该把毕业设计做到什么程度才能过关?3.…