Unity-Sprite Atlas+UGUI系统的运行原理

每日一句:别听世俗耳语,看自己的风景就好

目录

SA的原理:

SA的优点:

SA的缺点:

DrawCall是什么?

批处理是什么?

我们先了解一下UGUI系统的运行原理吧!


提到图集优化,我想引出一个经典的游戏优化案例:

《超级马里奥》的Tile压缩方法:

由于红白机的性能相比现在的家用主机来说极为有限,无论是储存器性能还是处理器性能,所以当时的开发者采用“Tile瓦片”(每个瓦片8X8像素大小)作为基本的图片存储单元,然后再把这些瓦片拼接在一起。

如此以来画面分辨率256X240的红白机用8X8瓦片来填满只需要32 * 30 = 960张瓦片,给每个瓦片一个0至255的编号,那么最多只需要960B来表示一个屏幕里的所有图片,并且瓦片的内容是重复的并且个数是有限的,所要求的存储性能以及内存性能都因此大大降低。

当然为了极致的性能压缩性能,那个时代的开发者也应用了不少的技巧:

1.一个角色的行走动画,用一张图片进行左右交替翻转就能实现,减少了存储压力。

2.天上的云地上的草叠加放置,表现大小规模不同。

3.角色的图片只存储一半,用的时候再翻转拼接,又进一步压缩了存储。

这些前人的智慧也对主流的游戏引擎有着深远影响:Sprite Atlas(精灵图集,以下统称SA)

不仅仅局限于以上描述的方面,SA甚至可以应用于2D 和 3D 项目中的 UI、粒子系统、贴图等等。

现在我们对SA进行一个详细的归纳总结:

SA的原理:

是一种将多张小图汇总,打包成为一个大图的技术。在游戏运行时只需要载入一张大图到内存便可以实现多个素材的载入,是一种优化性能的手段,减少多次DrawCall对性能的占用。

SA的优点:

将多个图片合并到一张大图中,减少多次DrawCall对性能的占用。

SA的缺点:

当不经常使用的素材被放到图集中时,即使改素材不被使用也会被载入内存,浪费了内存资源;并且图集的大小固定为长边的二次幂,如果图集内素材的大小差距过大,会直接造成储存的浪费。

前期要求:

首先我们先找到PackageManager,在Unity Registry中下载2D包。不然无法在项目中创建SA内容。


点击“install”,下载这个包

然后找到Project Setting选项>Editor>Sprite Atlas>Mode

Mode默认是Disabled,更改为Always Enabled,V1和V2两个版本目前没有很大的区别,选V1就行

其他两个选项的意思是:Enabled For Builds——在项目导出后应用图集,所以在编辑器里面看到的图集仍然是原来的那些图片。

为了保证项目能接近玩家原生感受选择Always Enabled。

SA的创建:

项目内右键Project>2D>Sprite Atlas创建SA。

这里如果没有前期准备的内容,就无法创建SA。

配置SA:

点击我们新创建的SA

解释一下该面板的几个重要内容的意义:

  1. Include in Build:是否在游戏发布后构建到游戏中
  2. Allow Rotation:是否允许旋转图片,如果勾选,在构建图集时可能会旋转对应的图片,建议禁用
  3. Tight Packing:选中可根据图片的轮廓而非默认矩形轮廓来打包精灵,让图片排列更紧密,建议禁用,否则UI元素在显示时可能会重叠显示其他的图片,因为在获取对应Sprite时是按矩形轮廓来获取的
  4. Padding:不同UI元素之间的间隔,单位为像素,避免图片之间过近导致显示出问题
  5. Objects for Packing:需要打包的UI元素,可以放文件夹或者单个图片,放文件夹可以将文件夹所有的图片打包进这个图集中,图片的格式需要设置为Sprite(2D and UI),一个图集最大的尺寸是2048*2048

以上为SA的使用方法以及原理当然还有其他的图集系统类似于Texture Atlas的内容,不过原理上也大同小异,下面我们深入的了解一下图集优化的内容。

前文提到了DrawCall,这里解释一下DrawCall的相关概念:

DrawCall是什么?

当我们在渲染一个物体时,需要通知GPU执行渲染的指令,这一过程叫做“DrawCall”。而调用DrawCall的次数越多,对GPU和CPU的性能开销就越大,本身电脑的性能就有限,因此我们便要减少DrawCall的次数,减轻对GPU的性能负担。所以开发者们就想到了上述类似Sprite Atlas的方法,以减少性能开销。

批处理是什么?

上面我们了解了Sprite Atlas的运行原理,而批处理便是该原理的名称;由于每一次DrawCall就可以大致理解为一个渲染批次(batch)。Draw call属于资源密集型的指令,图形API要为每个Draw call做大量的工作。造成CPU性能消耗的主要是渲染状态的切换导致的,例如切换到不同的材质,这会导致在图形驱动中产生密集的资源验证和切换。为了减少draw call的调用Unity引入了两种优化技巧:

  1. 动态批处理对于足够小的mesh,动态批处理通过将他们的顶点整合到一个批次中进行绘制。
  2. 静态批处理:通过将不会移动的静态物体合并到更大的mesh中,以提升渲染速度。

材质方面的要求

只有使用了相同材质的物体才能够实现批处理。如果两个不同的物体,使用的两个材质,只是纹理上的差别,那就把他们的纹理合并到一起,这样就可以使用同一个材质。脚本中使用Render.material属性时,会重新生成一个原来材质的拷贝,所以用Render.sharedMaterial可以保持材质的一致性(但是使用同一个材质的物体,都会被改变)。关于阴影,只要材质中使用的是相同的Shadow Pass,就可以实现批处理,即便他们不是同一个材质。

我们先了解一下UGUI系统的运行原理吧!

UGUI是在3D网格下建立起来的UI系统,它的每个元素都是通过3D模型网格的形式构建起来的。当UI系统被实例化时,首先要做的就是构建网格。【也就是说,Unity在制作一个图元,或者一个按钮,或者一个背景时,都会先构建一个方形网格,再将图片放入网格中。可以理解为构建了一个3D模型,用一个网格绑定一个材质球,材质球里存放要显示的图片。】

那么这里有一个问题界面上成千上万个元素就会拥有成千上万个材质球。如果GPU对每个材质球和网格都进行渲染,将会导致GPU的负担重大,怎么办呢?

UGUI对这种情况进行了优化,它

  1. 部分相同类型的图片集合起来合成一张图,
  2. 然后将拥有相同图片、相同着色器的材质球指向同一个材质球,
  3. 并且把分散开的模型网格合并起来,
  4. 这样就生成几个大网格和几个不同图集的材质球

以及少许整张的图集节省了很多材质球、图片、网格的渲染,UI系统的效率提升了很多,游戏在进行时也顺畅了许多。

这就是图集概念,它把很多张图片放置在一张图集上,使得大量的图片和材质球不需要重复绘制,只要改变模型顶点上的UV和颜色即可。

我们设想一下,如果每时每刻都在移动一个元素,那么UGUI系统就会不停地拆分合并网格,也就会不停地消耗CPU来使得画面保持应有的样子。这些合并和拆分的操作会消耗很多CPU,我们要尽一切可能节省CPU内存尽量把多余的CPU让给核心逻辑。UGUI系统在制作完成后,性能优劣差距很多时候都会出现在这里。

我们要如何想方设法合并更多的元素,减少重构网格的次数,以达到更少的性能开销目的呢?(UI优化)请阅读这篇文章啦

Unity—UI-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_63330263/article/details/136473724?spm=1001.2014.3001.5501本文成果由CSDN博主“Lyrissss_”与我共同创作

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

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

相关文章

cocosCreator动态生成二维码

cocosCreator 版本:3.7.2 开发语言:typeScript 我们在游戏开发中,经常会生成一个专属于玩家个人的二维码,比如说推广、充值等功能。 接到这个任务,在网上找了下,还是有很多教程的。但是这些教程大部分都是用…

Ollydbg动态分析MessageBoxA输出hellow world

一、目的 找到main函数找到调用的MessageBoxA函数 测试源码 #include <iostream> #include <windows.h>int main() {MessageBoxA(NULL, "Hellow World", "Title", MB_OK);return 1; }二、快捷键 指令快捷键说明RestartCtrlF2重新开始调试S…

buu[HCTF 2018]WarmUp(代码审计)

buu[HCTF 2018]WarmUp&#xff08;代码审计&#xff09; 题目 访问source.php <?phphighlight_file(__FILE__);class emmm{public static function checkFile(&$page){$whitelist ["source">"source.php","hint">"hint.php…

MySQL基础学习: SET FOREIGN_KEY_CHECKS = 0

文章目录 一、介绍二、使用方法三、注意事项 一、介绍 在MySQL中&#xff0c;SET FOREIGN_KEY_CHECKS 0; 是一个特殊的命令&#xff0c;用于临时禁用外键约束检查。这在你执行一些涉及多个表并且可能违反外键约束的批量操作时非常有用。 为什么需要禁用外键约束检查&#xf…

电脑键盘如何练习盲打?

电脑键盘如何练习盲打&#xff1f;盲打很简单&#xff0c;跟着我做&#xff0c;今天教会你。 请看【图1】&#xff1a; 【图1】中&#xff0c;红色方框就是8个基准键位&#xff0c;打字时我们左右手的8个手指就是放在这8个基准键位上&#xff0c;F键和J键上各有一个小突起&…

Spring6基础笔记

Spring6 Log4j2 1、概述 1.1、Spring是什么&#xff1f; Spring 是一款主流的 Java EE 轻量级开源框架 &#xff0c;Spring 由“Spring 之父”Rod Johnson 提出并创立&#xff0c;其目的是用于简化 Java 企业级应用的开发难度和开发周期。Spring的用途不仅限于服务器端的开发…

mysql图形化界面及将mysql注册成后台程序

安装图形化界面版本 右键新建数据库 字符集使用utf8防止以后数据库中存在中文字符导致乱码 将mysql注册成后台程序 cmd进入命令行界面 切换路径到cd /mysql/bin 将mysql注册成后台程序 mysqld.exe --install mysql1 (失败&#xff0c;说明没有权限) 以管理员身份打开成功…

ASP.NET防止流量攻击的措施

请求速率限制&#xff1a; // 在 Global.asax.cs 文件中 Application_BeginRequest 方法中添加以下代码 protected void Application_BeginRequest() {// 检查请求频率&#xff0c;限制每个 IP 地址的请求次数if (RequestThrottler.IsRequestLimitExceeded(Context.Request.Use…

如何跨过robots协议的限制爬取内容?

在讨论如何“跨过robots协议的限制爬取内容”之前&#xff0c;重要的是强调遵循网络礼仪和法律法规的必要性。robots协议&#xff08;Robots Exclusion Standard&#xff09;是网站所有者向网络爬虫&#xff08;包括搜索引擎和其他自动化工具&#xff09;传达其爬取意愿的一种方…

SYSTEM文件夹介绍(sys文件夹、deley文件夹、USART 文件夹、SysTick、printf函数、fputc函数、半主机模式)

参考 http://t.csdnimg.cn/P9H6x 一、sys文件夹介绍 在上述介绍的 sys 文件夹中&#xff0c;涉及了一些与系统控制、中断管理、低功耗模式、栈顶地址设置、系统时钟初始化以及缓存配置等相关的函数。以下是对每个功能的简要分析&#xff1a; 1.中断类函数&#xff1a; sys_n…

CCF20230901——坐标变换(其一)

CCF20230901——坐标变换&#xff08;其一&#xff09; #include<bits/stdc.h> using namespace std; int main() {int n,m,x[101],y[101],x1[101],y1[101];cin>>n>>m;for(int i0;i<n;i)cin>>x1[i]>>y1[i];for(int j0;j<m;j)cin>>x[…

uniapp 高德地图与百度地图精准定位,高德地图定位报错

目前我这边测试发现的问题 UNIAPP 获取定位的代码 在这里插入代码片 data的参数 data() {return {id: 0, // 使用 marker点击事件 需要填写idtitle: map,latitude: 39.909,longitude: 116.39742,covers: [{latitude: 39.909,longitude: 116.39742,width: 50,height: 50,iconPa…

负反馈系统中运放的相位裕度仿真、环路增益的stb仿真

这里没目录标题 一、引言二、巴克豪森判据、最坏情况下的相位裕度、相位裕度三、相位裕度与开环&#xff0c;环路&#xff0c;闭环增益的关系四、环路增益、闭环增益和相位的仿真4.1 运放为双入单出时4.1.1 系统的闭环增益4.1.2 stb仿真系统的环路增益和相位裕度&#xff08;环…

Python项目:数据可视化_下载数据【笔记】

源自《Python编程&#xff1a;从入门到实践》 作者&#xff1a; Eric Matthes 02 下载数据 2.1 sitka_weather_07-2021_simple.csv from pathlib import Path import matplotlib.pyplot as plt import csv from datetime import datetimepath Path(D:\CH16\sitka_weather_0…

python web自动化(Allure报告)

Allure详细安装请看之前的博客 1.Allure配置与⼊⻔ 运⾏⽤例&#xff0c;⽣成allure报告 pip install allure-pytest -i https://mirrors.aliyun.com/pypi/simple/ 运⾏⽤例&#xff0c;⽣成allure报告 # main.py import os import pytest if __name__ __m…

SpringBoot如何实现热部署

热部署 使用SpringBoot提供的DevTools实现热部署 原理&#xff1a;实时监控classpath下文件的变化&#xff08;即编译后的target目录&#xff09;&#xff0c;如果发生变化则自动重启 配置&#xff1a;添加DevTools的依赖即可&#xff08;需要开启IDEA的自动编译&#xff09…

ROS学习记录:用C++实现IMU航向锁定

前言 获取IMU数据的C节点 在了解了如何获取到IMU的姿态信息&#xff08;链接在上面&#xff09;后&#xff0c;接下来尝试实现让一个节点在订阅IMU数据的时候&#xff0c;还能发布运动控制指令&#xff0c;使机器人能对姿态变化做出反应&#xff0c;达到一个航向锁定的效果。 …

神奇动物在哪里,但导演是微软

大数据产业创新服务媒体 ——聚焦数据 改变商业 一说到计算机视觉&#xff0c;大多数人第一时间联想到的便是“人脸识别”、“自动驾驶“、道路检测”等跟我们日常生活息息相关的关键词。而在2024年的5月末&#xff0c;微软在GitHub上面上传了这样一个计算机视觉的项目&#x…

2024年华为OD机试真题-停车场车辆统计-C++-OD统一考试(C卷D卷)

题目描述: 特定大小的停车场,数组cars[]表示,其中1表示有车,0表示没车。车辆大小不一,小车占一个车位(长度1),货车占两个车位(长度2),卡车占三个车位(长度3),统计停车场最少可以停多少辆车,返回具体的数目。 输入描述: 整型字符串数组cars[],其中1表示有车,0…

通过Python爬取公告内容

在网络时代&#xff0c;信息获取变得更加便捷。通过网络爬虫技术&#xff0c;我们可以从互联网上快速获取各种信息。本文将介绍如何使用 Python 爬虫工具从指定网站上获取公告内容&#xff0c;并提取其中的关键信息。 1. 简介 在本文中&#xff0c;我们将使用 Python 的 requ…