Unity性能优化之纹理格式终极篇
知识早班车:
1、当n大于1时,2的n次幂一定能被4整除;证明:2^n = 2^2*2^(n-1) = 4*2^(n-1)
2、4的倍数不一定都是2的次幂;证明:4*3 = 12;12不是2的次幂
3、Pixel(像素)是组成图片的最小单位;Byte(字节)是计算机文件大小的最小单位;bit(比特/位)是计算机处理运算的最小单位
4、常见的RGB 16位,ARGB/RGBA 16位,RGB 24位,ARGB/RGBA 32位等,它们通常的通道分配有:
RGB 16位 = RGB565 = RGB555(最高位不用)、ARGB/RGBA 16位 = ARGB4444 = RGBA4444 = ARGB1555 = RGBA5551
RGB 24位 = RGB888、ARGB/RGBA 24位 = ARGB/RGBA6666、RGB 32位 = RGB888(剩余8位保留)、ARGB/RGBA 32位 = ARGB/RGBA8888
知识始发站
我们在做资源优化时,必然少不了对纹理格式的处理。任何图片文件格式在导入Unity后,都会被转换为Textur2D格式,然后我们可以在Texture2D的导入设置选项中根据不同平台,设置纹理的压缩格式。
那么,为什么我们需要纹理压缩格式呢?
例如RGB565、ARGB4444、ARGB1555、RGB888、ARGB8888等未经压缩的图片格式,是能够被GPU直接读取的原生纹理格式。但在低端硬件设备或移动平台下,有两个问题需要解决:内存+带宽;
1、例如ARGB8888格式中一个像素占4Byte,如果是512x512分辨率内存占用为:512x512x4B=1048576B=1M,这种内存消耗在低端设备上根本无法接受。
2、另一个重要的是数据传输时的带宽,带宽是发热的元凶,在渲染3D场景时,会有大量的贴图被传输到GPU,若不限制,总线带宽很快就会成为瓶颈,手机秒变暖手宝,严重的还会影响渲染性能。
因此我们需要一种内存占用既小又能被GPU读取的格式——压缩纹理格式。纹理压缩对应的算法是以某种形式的固定速率有损向量量化将固定大小的像素块编码进固定大小的字节块中。
有损:表示对于渲染来说,有损压缩是可以接受的,一般选择压缩格式时需要在纹理质量和文件大小上寻求一个平衡。
固定速率压缩:因为GPU需要能够高效的随机访问一个像素,这意味着对任意像素,解码速度不该有太大的变化。因此,我们常见的贴图压缩算法都是有损压缩。相反例如zip则是一种可变速率压缩。
向量量化:一种量化技术,将一组大量的点(向量)分成具有近似相同数量的最接近它们的点的组。每个组用它的质心点表示,因此存在数据误差,适用于有损压缩。放到纹理压缩中来理解,就例如将4x4块像素的颜色以2个基色来表示。
编码和解码速度:一般来说编码速度慢没关系,因为通常纹理压缩只需要在游戏打包时进行一次,对于用户运行时体验完全没有影响。但解码速度必须足够快,而且基本上不影响渲染性能。
压缩比:通常以比特率或每像素的平均比特数(bits per pixel, bpp)表示,常见的为1~8bpp。一般RGB原生纹理的像素指24位,即每个像素占24位(bit),现有4bpp表示每个像素占4位(bit),那么可认为4bpp表示压缩比例为6:1.
另Unity对导入的资源图片,不管是PNG格式还是JPG格式,统统都会转换为Unity引擎当中处理的Texture2D格式,
为什么我们不使用png,jpg这类常见的压缩格式?
尽管jpg、png的压缩率很高,但并不适合纹理,主要问题是不支持像素的随机访问,这对GPU相当不友好,GPU渲染时只使用需要的纹理部分,我们总不能为了访问某个像素去解码整张纹理吧?不知道顺序,也不确定相邻的三角形是否在纹理上采样也相邻,很难有优化。这类格式更适合下载传输以及减少磁盘空间而使用。
常见的纹理压缩格式
1、ETC
ETC主要是android的标准压缩方案,其原理简单来说是将4x4的像素块编码为2x4或4x2像素的两个块的方法,每个块指定一个基色,每个像素的颜色通过一个编码为相对这些基色偏移的灰度值确定。
Unity中常用的ETC压缩格式有:
RGB ETC1 4bit:4bit/pixel,对RGB压缩比为6:1,不支持alpha,绝大多数android设备都支持
RGB ETC2 4 bit:4 bits/pixel,对RGB压缩比6:1。不支持Alpha,ETC2兼容ETC1,压缩质量可能更高,但对于色度变化大的块误差也更大,需要在OpenGL ES 3.0和OpenGL 4.3以上版本。
RGBA ETC2 8bit:8 bits/pixel,对RGBA压缩比4:1。支持完全的透明通道,版本要求同上。
RGB +1bit Alpha ETC2 4bit:4 bits/pixel。支持1bit的Alpha通道,也就是只支持镂空图,图片只有透明和不透明部分,没有中间的透明度。
2、DXT 原名S3TC(S3 Texture Compression )
其原理简单来说,是由一对低精度的“基色”来描述一个4x4的RGB像素块,并允许每个像素在这些基色之间指定一个插值。S3TC有多种变体,每种都是为特定类型的图像数据设计,但它们都是将4x4的像素块转换为64位或128位的数据
3、ASTC
ASTC是android和ios平台下的一种高质量压缩方式,支持android5.0和iphone6以上的机型。它也是一种基于块的有损压缩算法,它的块是固定大小为128位,虽然是固定大小,但是与先前格式的固定4x4块不同,每个纹理在这128位中可以有不同大小的块,可以是方形和非方形,2D纹理编码中,它从4x4到12x12像素都有,对应的压缩比1~8bpp。它的特点有很多:
较高的灵活性:支持1-4分量的贴图
压缩率/质量灵活可变:根据不同图片会选择不同压缩率级别的算法
支持2D/3D贴图
跨平台:iOS、安卓、PC
同时支持LDR和HDR:BC6H虽然支持HDR但不支持Alpha通道
块越大,压缩质量越差,但是图片越小。ASTC的比特率可以在小数级变化,这种技术称为BISE(Bounded Integer Sequence Encoding)。
但要注意的是尽管纹理可以被编码为1-4通道图像,但是解码后的值总是以RGBA格式输出。在LDR sRGB模式下,颜色值以8位整数的形式返回,而如果是HDR则将以16位浮点数的形式返回。
在设置ASTC格式时,还需注意一下几点:
法线贴图:尽量选择4x4,避免丢失过多数据。
细节处的贴图:选择4x4或6x6,否则会丢失细节。
一般贴图:选择6x6或8x8。4、无关紧要但尺寸特别大的图:可考虑8x8或10x10或12x12,不然打包出来太大。
通过以上三种压缩格式我们发现,三种压缩算法中都用到了4x4的像素块做运算,这让我们不禁想到了,我们在做图片优化时,经常要求美术同学在输出图片尺寸时,保持长宽为4的倍数的原因了,这样我们在对导入Unity的图片进行压缩格式设置的时候才会起到更好的效果。不过,可能还会有同学提出疑问,为什么有时候会听到把图片尺寸设置成2的次幂呢?这是因为最初的ETC压缩算法不支持透明通道,图片宽高要求必须是2的次幂,还有就是ios平台下的PVRTC压缩格式也是仅支持2的次幂,再加上当n>1时,2^n一定为4的倍数,所以就有要求图片输出尺寸为2的次幂的要求;好在现在andorid平台大多都支持ETC1/ETC2,ETC2是ETC的扩展,支持透明通道,且图片宽高只要是4的倍数即可;PC平台也都支持DXT1/DXT5/DXT5,DXT3和DXT5原理同DXT1一样,只不过DXT3和DXT5支持透明通道,也要求图片宽高只要是4的倍数即可;ASTC格式也被越来越多的平台所支持,所以我们在设置图片尺寸时,只需要设置为4的倍数即可。还有就是Generate Mip Maps如果是开启状态下,只有2的次幂才能被压缩,因为生成mipmap必须是2的次幂的像素。
知识小贴士:
1、对于图片,现在有sprite atlas来对图片进行管理,凡是要打进图集的图片,尺寸可以不必遵循4的倍数设置,因为这些图最终是打进图集的,我们可以对图集进行4的倍数的设置,不过这样做的一个缺点就是图集为了保持设置的4的倍数的尺寸,不得不浪费一些空间,所以最好的方式还是将所有图片都设置成4的倍数;不进图集的图片的尺寸就要严格控制了,最好为4的倍数,且最大尺寸不要超过1024x1024。
2、关闭Read/Write 选项,因为开启此选项将会允许从脚本来访问纹理数据,将会产生纹理数据的副本, 副本会占用内存, 等同于一个纹理数据会有双倍的内存消耗。
3、Filter Mode设为Bilinear的纹理:Trilinear 三线性过滤(三线性插值), 纹理会在不同的 mip 水平之间进行模糊 ,从而增加 GPU 开销。
4、Sprite纹理关闭Mipmap:Mipmap 开启后,内存会是未开启 Mipmap 的 1.33 倍, 因为 Mipmap 会生成一组长宽依次减少一倍的纹理序列, 一直生成到 1*1。Mipmap 提升 GPU 效率; 一般用于 3D 场景或角色, UI 不建议开启。
5、Wrap 模式设置为 Clamp:Wrapmode 使用了 Repeat 模式, 容易导致贴图边缘出现杂色
以PC平台为例:
如果导入的图片长宽尺寸为4的倍数也为2的次幂,则会被压缩为RGB Compressed DXT1 或者RGBA Compressed DXT5;
如果导入的图片长宽为4的倍数但不为2的次幂,则会被压缩为(NPOT)RGB Compressed DXT1 或者(NPOT)RGBA Compressed DXT5;
如果导入的图片长宽不为4的倍数也不为2的次幂,则会被压缩为(NPOT) RGB24/(NPOT) RGBA32,这些都为未压缩格式,非常占用内存
相关文章:
Unity性能优化之纹理格式终极篇
知识早班车:1、当n大于1时,2的n次幂一定能被4整除;证明:2^n 2^2*2^(n-1) 4*2^(n-1)2、4的倍数不一定都是2的次幂;证明:4*3 12;12不是2的次幂3、Pixel(像素)是组成图片…...
【Spark分布式内存计算框架——Spark SQL】9. Dataset(下)RDD、DF与DS转换与面试题
5.3 RDD、DF与DS转换 实际项目开发中,常常需要对RDD、DataFrame及Dataset之间相互转换,其中要点就是Schema约束结构信息。 1)、RDD转换DataFrame或者Dataset 转换DataFrame时,定义Schema信息,两种方式转换为Dataset时…...
Windows 环境下,cmake工程导入OpenCV库
目录 1、下载 OpenCV 库 2、配置环境变量 3、CmakeLists.txt 配置 1、下载 OpenCV 库 OpenCV官方下载地址:download | OpenCV 4.6.0 下载完毕后解压,便可以得到下面的文件 2、配置环境变量 我们需要添加两个环境变量,一个是 OpenCVConfi…...
微服务架构设计模式-(16)重构
绞杀者应用程序 由微服务组成的应用程序,将新功能作为服务,并逐步从单体应用中提取服务来实现。好处 尽早并频繁的体现价值 快速开发交付,使用 与之相对的是“一步到位”重构,这时间长,且期间有新的功能加入ÿ…...
数据结构:归并排序和堆排序
归并排序 归并排序(merge sort)是利用“归并”操作的一种排序方法。从有序表的讨论中得知,将两个有序表“归并”为一个有序表,无论是顺序表还是链表,归并操作都可以在线性时间复杂度内实现。归并排序的基本操作是将两个位置相邻的有序记录子序列R[i…m]R[m1…n]归并为一个有序…...
基于easyexcel的MySQL百万级别数据的excel导出功能
前言最近我做过一个MySQL百万级别数据的excel导出功能,已经正常上线使用了。这个功能挺有意思的,里面需要注意的细节还真不少,现在拿出来跟大家分享一下,希望对你会有所帮助。原始需求:用户在UI界面上点击全部导出按钮…...
js-DOM02
1.DOM查询 - 通过具体的元素节点来查询 - 元素.getElementsByTagName() - 通过标签名查询当前元素的指定后代元素 - 元素.childNodes - 获取当前元素的所有子节点 - 会获取到空白的文本子节点 …...
作为一名开发工程师,我对 ChatGPT 的一些看法
ChatGPT 又又火了。 ChatGPT 第一次爆火是2022年12月的时候,我从一些球友的讨论中知道了这个 AI 程序。 今年2月,ChatGPT 的热火更加猛烈,这时我才意识到,原来上次的热火只是我们互联网圈子内部火了,这次是真真正正的破圈了,为大众所熟悉了。 这个 AI 程序是一个智能问…...
Flask中基于Token的身份认证
Flask提供了多种身份认证方式,其中基于Token的身份认证是其中一种常用方式。基于Token的身份认证通常是在用户登录之后,为用户生成一个Token,然后在每次请求时用户将该Token作为请求头部中的一个参数进行传递,服务器端在接收到请求…...
波奇学数据结构:时间复杂度和空间复杂度
数据结构:计算机存储,组织数据方式。数据之间存在多种特定关系。时间复杂度:程序基本操作(循环等)执行的次数大O渐进法表示法用最高阶的项来表示,且常数变为1。F(n)3*n^22n1//F(n)为…...
移动OA办公系统为企业带来便捷办公
移动OA系统是指企业员工同手机等移动设备来使用OA办公系统,在外出差的员工只需要通过OA系统的手机APP就可以接收相关的新信息。PC办公与移动OA办公的相结合,构建用户单位随时随地办公的一体化环境。 相比PC办公,移动OA办公给企业带来更多的便…...
什么是Type-c口?Type-c口有什么优势?
什么是Type-C接口 Type-C接口有哪些好处坏处 说起“Type-C”,相信大家都不会陌生,因为最近拿它大做文章的厂商着实不少,但要具体说清楚Type-C是什么,估计不少人只能说出“可以正反插”“USB的一种”之类的大概。其实,T…...
Go开发者常犯的错误,及使用技巧 (1)
代码规范 命名不规范 变量名要有意义,不能随便取a,b,c 如果只是纯粹的算法题,这样问题不大。但工程上的代码可读性要求较高,不能随意命名变量名,例如: for _, v : range userList {// ... }如果for语句块简短还好&…...
Servlet 作业
一、填空题1. Servlet 中使用Session 对象的步骤为:调用HttpServletRequest.getSession()的得到Session对象,查看Session对象,在会话中保存数据。2. http 全称是_HyperText Transfer Protocol3. 用户可以有多种方式请求Servlet,如…...
Hive高阶函数:explode函数、Lateral View侧视图、聚合函数、增强聚合
Hive高阶函数 文章目录Hive高阶函数explode函数Lateral View侧视图原理语法聚合函数增强聚合grouping setsCUBEROLL UPexplode函数 explode接收map、array类型的数据作为输入,然后把输入数据中的每个元素拆开变成一行数据,一个元素一行。explode执行效果…...
信息系统服务管理
一、信息系统服务业及发展二、信息系统工程监理的概念及发展三、信息系统运行维护的概念和发展 IT服务管理(ITSM) 四、信息技术服务管理的标准和框架 IT服务标准体系(ITSS) 一、信息系统服务业及发展 总结:前景很好 二、信息系…...
Windows10 安装ElasticStack8.6.1
一、安装ElasticSearch8.6.1 1.官网下载ElasticSearch8.6.1压缩包后解压 2.安装为服务 elasticsearch-service.bat install 3.运行 elasticsearch-service.bat start 4.通过浏览器访问 http://localhost:9200/ 提示需要登录,但不知密码是啥。 5.重置密码 ela…...
gRPC 非官方教程
一、 简介 gRPC的定义: 一个高性能、通用的开源RPC框架主要面向移动应用开发: gRPC提供了一种简单的方法来精确地定义服务和为iOS、Android和后台支持服务自动生成可靠性很强的客户端功能库。基于HTTP/2协议标准而设计,基于ProtoBuf(Protoc…...
6.2【人工智能与深度学习】RNN、GRU、远程服务管理、注意力、Seq2 搜索引擎和内存网络
【人工智能与深度学习】RNN、GRU、远程服务管理、注意力、Seq2 搜索引擎和内存网络底层原理介绍 深度学习架构循环神经网络(RNN)循环网络:摊开循环的网络的循环循环神经网络的技巧乘法模组注意模组门控循环单元(GRU)长期短期记忆(Long Short-Term Memory,简称LSTM)序列到序列…...
软件工程复习
软件工程简介 软件: -在执行时提供所需的功能和性能的指令; -使程序能够充分操作信息的数据结构; -描述这些程序的操作和使用情况的文档。 软件定义:计算机程序和相关文档。 软件特点:软件没有质量;它并不…...
将Nginx 核心知识点扒了个底朝天(二)
Nginx 是如何实现高并发的? 如果一个 server 采用一个进程(或者线程)负责一个request的方式,那么进程数就是并发数。那么显而易见的,就是会有很多进程在等待中。等什么?最多的应该是等待网络传输。 而 Nginx 的异步非阻塞工作方…...
【PowerQuery】PowerBI 的PowerQuery支持的数据集成
PowerBI中的各个Power组件已经被深度集成到PowerBI中,不再作为像Excel一样的独立组件而存在。在PowerBI的界面中为了快速导入这些常用的数据,也有相应的快速导入界面。PowerBI的快速导入界面位于主页面中,下图就是PowerBI的快速导入界面。 在PowerBI中的数据导入界面相比Exc…...
scipy spatial transform Rotation库的源代码
前几日研究scipy的旋转,不知道具体里面怎么实现的,因此搜索一番。 发现Rotation在scipy的表达是用四元数的 https://github.com/jgagneastro/coffeegrindsize/edit/master/App/dist/coffeegrindsize.app/Contents/Resources/lib/python3.7/scipy/spatia…...
JAVA文件操作
JAVA文件操作 文章目录JAVA文件操作1.属性2.构造方法3.方法3.1创建文件3.2 文件删除3.3创建目录3.4文件名3.5 文件重命名3.6查看文件的可读性 Java中通过 java.io.file类来对文件(目录)进行抽象的描述。注意, 有File对象时,不代表真实存在该文件。1.属…...
字符串匹配 - 模式预处理:BM 算法 (Boyer-Moore)
各种文本编辑器的"查找"功能(CtrlF),大多采用Boyer-Moore算法,效率非常高。算法简介在 1977 年,Robert S. Boyer (Stanford Research Institute) 和 J Strother Moore (Xerox Palo Alto Research Center) 共…...
RV1126笔记三十:freetype显示矢量字体
若该文为原创文章,转载请注明原文出处。 在前面介绍了使用取模软件,可以自定义OSD,这种做法相对不灵活,也无法变更,适用大部分场景。 如果使用opencv需要移植opencv,芯片资源相对要相比好,而且移植比freetype复杂。 这里记录下如何使用freetype显示矢量字体,使用fre…...
polkit pkexec 本地提权漏洞修复方案
polkit pkexec 本地提权漏洞 漏洞细节,polkit pkexec 中对命令行参数处理有误,导致参数注入,能够导致本地提权。 解决建议 1、无法升级软件修复包的,可使用以下命令删除pkexec的SUID-bit权限来规避漏洞风险: chmod 0…...
es-06聚合查询
聚合查询 概念 聚合(aggs)不同于普通查询,是目前学到的第二种大的查询分类,第一种即“query”,因此在代码中的第一层嵌套由“query”变为了“aggs”。用于进行聚合的字段必须是exact value,分词字段不可进行…...
面试知识点准备与总结——(并发篇)
目录线程有哪些状态线程池的核心参数sleep和wait的区别lock 与 synchronized 的异同volatile能否保证线程安全悲观锁和乐观锁的区别Hashtable 与 ConcurrentHashMap 的区别ConcurrentHashMap1.7和1.8的区别ThreadLocal的理解ThreadLocalMap中的key为何要设置为弱引用线程有哪些…...
Django框架之模型视图-URLconf
URLconf 浏览者通过在浏览器的地址栏中输入网址请求网站对于Django开发的网站,由哪一个视图进行处理请求,是由url匹配找到的 配置URLconf 1.settings.py中 指定url配置 ROOT_URLCONF 项目.urls2.项目中urls.py 匹配成功后,包含到应用的urls…...
手机社交网站模板/广州搜索排名优化
题目: 给定一棵二叉树,返回所有重复的子树。对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可。 两棵树重复是指它们具有相同的结构以及相同的结点值。 示例 1: 1/ \2 3/ / \ 4 2 4/4下面是两个重复的子树&am…...
地产网站建设方案/网址查询工具
编译原理_哈尔滨工业大学_中国大学MOOC(慕课)...
学习网站开发/网站搭建关键词排名
● centos 7编译高版本内核: linux-3.13.10 过程相对简单: 1. 安装依赖 yum install ncurses-devel 2. 将linux内核解压缩到/usr.src/ 3. make 4. make modules_install 5. make install 6. 重起 转载于:https://www.cnblogs.com/volcanorao/p/6478092.h…...
郑州建网站公司/乐陵市seo关键词优化
1、本系统的后台使用mysql数据库,SSH 框架,前端使用ExtJs实现。因为系统需要用到权限管理,所以作此记录,权限管理精确到前端的每一个按钮,甚至每一个action请求。废话不多说,直接进入主题(一&am…...
营销型网站外包/山东网站seo
第一部分必读系列: 01.学习算法和刷题的思路指南 02.学习数据结构和算法读什么书 03.动态规划解题套路框架 04.动态规划答疑篇 05.动态规划答疑篇 06.回溯算法解题套路框架 07.二分查找解题套路框架 08.滑动窗口解题套路框架 09.双指针技巧总结 10.BFS算法套…...
做高性能的网站 哪门语言好/今日腾讯新闻最新消息
情况: DropDownList控件使用List<SelectListItem>()设置下拉选项和默认值。当控件的Name和后台的ViewBag(或ViewData)的Key重复,会导致选中状态无效。 规则如下1、DropDownList数据源可从ViewBag(或ViewData&…...