在做手机游戏时可能会遇到这些问题: UI 同学天天抱怨 iOS 上一些透明贴图压缩后模糊不堪 一些古早的 Android 手机上同样的贴图吃内存超过其他手机数倍,游戏经常闪退 这篇文章给出了一种手机游戏项目中通用的解决方案:分离贴图 alpha 通道,及其基于 Unity 引擎的实现过程和细节。其中思路主要来自于 https://zhuanlan.zhihu.com/p/32674470,本文是对该方法的实践和补充。 为什么要分离 1. 为什么会出现这些问题 要弄明白这些问题的由来,首先要简单解释一下贴图压缩格式的基础概念。 为了让贴图在手机中运行时占用尽可能少的内存,需要设置贴图的压缩格式,目前 Unity 支持的主要压缩格式有:android 上的 ETC/ETC2,iOS 上的 PVRTC,以及未来可能会使用的 ASTC。这几个压缩格式有自己的特点:
一般来说,目前 Unity 的手机游戏 android 上非透明贴图会使用 RGB Compressed ETC 4bits,透明贴图可以使用 RGBA Compressed ETC2 8bit,iOS 非透明贴图使用 RGB Compressed PVRTC 4bits,透明贴图使用 RGBA Compressed PVRTC 4bits。 这里的 bits 概念的意思为:每个像素占用的比特数,举个例子,RGB Compressed PVRTC 4bits 格式的 1024x1024 的贴图,其在内存中占用的大小 = 1024x1024x4 (比特) = 4M (比特) = 0.5M (字节)。 我们可以看到,在 iOS 上,非透明贴图和透明贴图都是 4bpp(4bits per pixel)的,多了透明通道还是一样的大小,自然 4bpp 的透明贴图压缩出来效果就会变差,而实机上看确实也是惨不忍睹。这是第一个问题的答案。 一些古早的 android 机,由于不支持 OpenGL es 3.0,因此 RGBA Compressed ETC2 8bit 的贴图一般会以 RGBA 32bits 的格式存在于内存中,这样内存占用就会达到原来的 4 倍,在老机器低内存的情况下系统杀掉也不足为奇了。这是第二个问题的答案。当然,需要说明的是,现在不支持 OpenGL es 3.0 的机器的市场占有率已经相当低了(低于 1%),大多数情况下可以考虑无视。 更多的贴图压缩格式相关内容可以参考这里:https://zhuanlan.zhihu.com/p/113366420 2. 如何解决问题 要解决上面图片模糊的问题,可以有这些做法:
不压缩显然是不可能的,毕竟 32bpp 的内存消耗对于手机来说过大了,尤其对于小内存的 iOS 设备更是如此。所以我们考虑分离 alpha 通道,将非透明部分和透明部分拆成两张图(如下所示)。 至于其内存占用,一般来说会把非透明部分拆成 RGB Compressed PVRTC 4bits,而透明通道部分可以使 RGB Compressed PVRTC 4bits,也可以是 Alpha8 格式(8bpp)。Alpha8 格式似乎不同版本 Unity 对于 Mali 芯片的手机支持度不同,我没有做深入研究。测试中,我使用了 RGB Compressed PVRTC 4bits 格式来压缩透明通道贴图,效果已经完全可以接受了。 如何分离 1. 方案 1 我们很自然而然的会想到,继承 SpriteRenderer/Image 组件去实现运行时替换材质来达到目的。这种方案有一些缺点,对于已经开发到后期的项目来说,要修改所有的组件成本非常高,更不用说在加入版本控制的项目中,修改 prefab 的合并成本也非常高了;另外对于已经使用自定义材质的组件来说也很不方便。 2. 方案 2 直接修改 Sprite 的 RenderData,让其关联的 texture,alphaTexture 等信息直接在打包时被正确打入包内。 这样做的好处就是不需要去修改组件了,只要整个打包流程定制化好以后就能够一劳永逸了。而对于大多数商业项目来说,定制打包流程基本是必须的,所以这个也就不算是什么问题了。 实现细节 首先说明一下,本方案在 2017.4 测试通过,其中打图集是采用已经废弃的 Sprite Packer 的方式,至于 Sprite Atlas 的方式,我没有研究过,但我觉得应该都可以实现,只是可能要改变不少流程。 下面说明一下具体实现,在打包之前大致流程如下: // 刷新图集缓存 大致解释一下上面的流程:
最后,在打包前,禁用 SpritePacker,避免其在打包时重写打了图集并覆写了 Sprite 的 RenderData 其中,关于生成 Alpha 通道贴图,需要注意的是使用图集中的散图位置等信息,将压缩前的顶点信息直接渲染到贴图上,这样透明通道贴图就不会受到压缩的影响。 // 临时渲染贴图 在将透明通道贴图写文件有一点需要注意的是:由于可能打的图集会产生多个 Page,这些 Page 的贴图名都是相同的,如果直接保存可能造成错误覆盖,所以需要使用一个值来区分不同 Page,这里我们使用了 Texture 的 hash code。 // 支持多 page 图集 接下来再说明一下最重要的写 SpriteRenderData 部分。 var spr = spriteEntry.Sprite; 需要修改的部分的含义,这里面的注释已经写的很清楚了,简单看一下能够大致理解。其中还有几个概念需要说明一下: 在 Sprite 的导入设置中,会被要求设置 MeshType,默认的是 Tight,其效果会基于 alpha 尽可能多的裁剪像素,而 Full Rect 则表示会使用和图片纹理大小一样的矩形。 这两个选项在达成图集时,如果你的散图周围的 alpha 部分比较多,使用 full rect 时就会看到图片分的很开,而使用 tight,表现出来的样子就会很紧凑,效果为下面几张图: 上面这个散图原图,可以看到周围透明部分较多 上面这个是使用 Tight 的 mesh type 打成的图集,可以看到中间的间隔较少 上面这个是使用 full rect 的 mesh type 打成的图集,可以看到中间的间隔较大。 一般我们会使用 Tight,那么我在上面代码中就需要对 tight 相关的一些数值做计算,具体如何计算直接看代码吗,应该不难理解。 其中还有一个获取计算散图(full rect)在图集中的 rect 的方法 GetTextureFullRectInAtlas,代码如下: private static Rect GetTextureFullRectInAtlas(Texture2D atlasTexture, Vector2[] uvs, Vector2[] atlasUvs) 最后,需要在自定义打图集规则,并在判断需要分离 alpha 通道的贴图,修改其对应压缩格式,如 RGBA ETC2 改 RGB ETC,RGBA PVRTC 改 RGB PVRTC。这样做是为了打图集生成一份不透明贴图的原图。大致代码如下: // 需要分离 alpha 通道的情况 至于如何自定义打图集的规则,可以参考官方文档:https://docs.unity3d.com/Manual/SpritePacker.html 一些补充 1. 在手机上 UI.Image 显示的贴图为丢失材质的样子 原因在于 Image 组件使用这套方案时,使用了一个内置的 shader:DefaultETC1,需要在 Editor -> Project Settings -> Graphics 中将其加入到 Always Included Shaders 中去。 2. 分离 alpha 通道的贴图的 sprite 资源打入包内的形式 通过 AssetStudio 工具看到,下图是没有分离 alpha 通道的散图的情况,可以看到每一个 Sprite 引用了一张 Texture2D 下图是分离了 Alpha 通道的图集的情况,可以看到,这个 AssetBundle 包中只有数个 Sprite,以及 2 张 Texture2D(非透明贴图和透明通道贴图)。 3. 如何知道需要修改 Sprite 的哪些 Render Data 在实践尝试的过程中,通过 UABE 工具来比较不分离 alpha 通道和分离 alpha 通道的两种情况下 Sprite 内的 Render Data 的不同,来确定需要修改哪些数据来达到目的。 从下图可以看出(左边是正常图集的数据,右边是我尝试模拟写入 RenderData 的错误数据),m_RD 中的 texture,alphaTexture,textureRect,textureRectOffset,settingsRaw,uvTransform 这些字段都需要修改。因为我无法接触到源码,所以其中一些值的算法则是通过分析猜测验证得出的。 4. m_RD.settingsRaw 的值的意义是什么 从 AssetStudio 源码中可以找到 settingsRaw 的一部分定义:
其中正常生成的图集的值 67,表示 SpriteMeshType(tight) + SpritePackingMode(rectangle) + packed。 5. 在 Unity 2017 测试通过,其他版本可以通过吗 并不确定。通过查看 AssetStudio 源码,可以看到序列化后有许多跟 Unity 版本相关的不同处理(下图),如果在不同版本出现问题,可以通过上面对比打好的 AssetBundle 包的 Sprite 的 RenderData 的方式来排查是否需要填写其他数据。 延伸思考 如果我们把一开始刷新图集缓存的操作更换成 TexturePacker 的话,是否可以使用 TexturePacker 中的一些特性来为图集做优化和定制呢?这是可能的,但是这也不是简单就能做到的东西,还是很繁琐的,不过的确是一个不错的思路,有需要的同学可以研究一下。 参考资料 IOS 下拆分 Unity 图集的透明通道(不用 TP): https://zhuanlan.zhihu.com/p/32674470 [2018.1] Unity 贴图压缩格式设置: https://zhuanlan.zhihu.com/p/113366420 (Legacy) Sprite Packer: https://docs.unity3d.com/Manual/SpritePacker.html 文中提到的工具: AssetStudio,一个可以轻松查看 AssetBundle 内容的工具: https://github.com/Perfare/AssetStudio UABE,可以解包/打包 AssetBundle,并查看其中详细数据的工具: https://github.com/DerPopo/UABE 代码仓库: 以上的代码都会整理在代码仓库中,该 demo 包含了一个完整的测试实例 https://github.com/RayRiver/UnityAlphaSeparateDemo 来源:indienova 原文:https://indienova.com/indie-game-development/unity-alpha-separate/ |
相关下载 |
首汽约车与差旅及费用管理供应商SAP Concur,就企业级业务达成战略合作,将为广大企业用户打造端到端的员工出行体验及费用管理方案,提高员工报销效率及企业费用管理水平。详情>>
随着炉石传说新版本通灵学院即将上线,官方也公布了新版本中的几张新卡牌,这些卡牌或许会给天梯冒险注入新的活力与新的对局。以下是通灵学院盗贼新卡秘密通道的简介,好好利用详情>>
备受期待的新作——Steam人气游戏《Mirror》开启续作开发计划《Mirror 2》! 并首次在Kickstarter开启众筹项目。 由2D向3D进化,突破次元!详情>>
在今年五月更新的 Edge Canary 通道版本中,微软为 PDF 文档添加了 Read Aloud 功能支持。在经过一个多月的改进之后, 这项功能登陆到 Beta 通道版本中 。 Edge 团队在今详情>>
千呼万唤始出来 2020 ChinaJoy 预约购票通道 即日起正式上线啦 没有什么能够阻挡 对ChinaJoy的向往 快爆手速 大家冲鸭 !!!!!! ▼ 主办声明 应《上海市会详情>>
在5月20日发布iOS 13.5版本更新之后,今天苹果关闭了iOS 13.4.1的签名通道,意味着用户无法降级到该版本。 iOS 13.4.1更新幅度并不大,主要修复了此前引入的 bug,曾错误地阻详情>>
《未定事件簿》定音测试自5月21日11:00开服测试以来,来自各地的新手律师们踊跃参与,服务器异常火爆,《未定事件簿》项目组十分感谢律师们的支持与厚爱详情>>
古代通道的怪能掉很多好东西,所以很多玩家都想去古代通道,但是不知道它在哪里,下面小编就给大家带来暗黑2古代通道位置介绍,一起来看看吧! 暗黑2古代通道在哪里详情>>
原标题:有些小区生命通道还是不通 红莲晴园2号楼前消防通道被车占据。 新村三里飞线充电就在燃气箱详情>>
来源:微信公众号 光通信观察 作者:水易 据以色列媒体Haaretz报道,以色列很快将在Google不断扩张的全球海缆网络中占据重要位置。谷歌正在计划一条名为Blue详情>>
DNF最近又出了很多的活动,其中微信中活动比较有趣,需要玩家回答问题,下面就跟随小编了解一下具体内容把! 是谁找到逃生通道的 A西岚 B艾丽丝 C赫尔德 D理查详情>>
原标题:18公里!他们让出一条生命通道 5月1日 浙江台州的高速路上 出现了暖心一幕: 长达18公里的路段中 司机纷纷自觉让行 为一位受伤孕妇 让出了“生详情>>
原标题:18公里!他们让出一条生命通道! 5月1日 浙江台州的高速路上 出现了暖心一幕: 长达18公里的路段中 司机纷纷自觉让行 为一位受伤孕妇 让出了“详情>>
不管什么时候,命都比车重要! 干得漂亮~ 详情>>
DNF是谁找到逃生通道的答案是什么?在DNF里,会有着各种各样的问题,其中就有人问是谁找到逃生通道的答案是什么?下面就去看看这款答案吧。是谁找到逃生通道的 A西岚 B艾丽丝 C赫详情>>
原标题:环鄂“五省一市”省际通道畅行 人便其行,货畅其流。 3月30日,湖北日报全媒记者继续探访环鄂交通状况,发现我省与湘、赣、皖、豫、陕、渝“五省详情>>
12月21日凌晨4:00起,京藏高速公路五环专用通道正式启用,机动车从京藏高速前往北五环路将经行五环专用通道到达,车辆可不停车、不领卡直接通行。此外,京开高详情>>
记者从北京市交通委获悉,自2019年12月21日凌晨4:00起,京藏高速公路五环专用通道正式启用。届时,机动车从京藏高速前往北五环路将经行五环专用通道到达,车辆详情>>
原标题:消防通道被车堵,为何总是治不住 胡印斌 12月2日晚,沈阳一小区高层住宅发生大火,火势由低向高蔓延。据报道,离楼体最近的消防通道被车辆堵塞,救援详情>>
原标题:共建西部陆海新通道冷链产业 12月20日,2019年重庆江津·广西防城港跨区域合作“一会一节”活动(简称“一会一节”)在江津双福国际农贸城开幕。详情>>
原标题:深中通道首节钢壳沉管完成浇筑并纵移成功 深中通道首节钢壳沉管完成浇筑并纵移成功(央广网发 通讯员供图) 深中通道首节钢壳沉管完成浇筑并详情>>
原标题:深中通道架设首片箱梁 在建的深(圳)中(山)通道是集“桥、岛、隧、水下互通”于一体的跨海集群工程,全长约24公里,包括6.8公里海底隧道和17.5详情>>
_contentraw">TheGameAwards2019今日公开了全部奖项的提名名单,颁奖典礼将于北京时间12月13日9点30举行。本届TGA2019依旧在bilibili开放了投票通道,你可以前往B站参与投票,绑详情>>
原标题:降级再见:苹果关闭iOS 13.2系统验证通道 IT之家11月15日消息 在上周发布iOS 13.2.2正式版之后,苹果今日停止了对iOS 13.2的验证,这意味着用户详情>>
原标题:红岭创投兑付通道起波澜 有支付机构称已停止为部分P2P提供支付通道 每经记者:谢婧 每经编辑:卢九安 图片来源:摄图网 近日,红岭创投电子商务详情>>
原标题:叶青:进一步堵住“赌博”受贿通道 2013年之前,一些官员与利益索取者赌博、借所谓“赢钱”受贿的现象相当严重。记得某省有个交通厅长居然长期详情>>
刺客信条枭雄序列5秘密通道在哪 秘密通道位置。很多玩家都找不到刺客信条枭雄序列5秘密通道在什么地方,今天99单机网小编就给大家介绍刺客信条枭雄序列5秘密通道位置,... 详情>>
刺客信条枭雄很多玩家在过完美主线的时候序列6有个要求是找到秘密通道。可是宫殿太大不知道在哪里呀。来看看99单机小编的刺客信条枭雄序列6秘密通道在哪 秘密通道... 详情>>
《星界边境》翼人副本水路隐藏通道在哪?如何进入?很多玩家并不清楚,今天小编就为大家带来了《星界边境》翼人副本隐藏通道进入方法,一起来看看吧。 星界边境翼人... 详情>>
苹果iOS12.0.1正式版系统验证通道关闭了吗?针对这个问题,下面小编就为玩家带来苹果iOS12.0.详情>>
站长之家(ChinaZ.com) 10月9日 消息:据快科技报道,今天,苹果悄悄的关闭了iOS 11. 4的系统验证通道,这也意味着用户将无法从iOS12 降级回iOS11 系统。目前市... 详情>>
猫和老鼠手游秘密通道位置介绍,当老鼠队集齐5块奶酪后,需要大家寻找金钥匙打开秘密通道逃跑,那么秘密通道在哪儿呢,一起来看看吧。 如图,秘密通道固定刷在餐厅 详情>>
排队排的慢?快速通道来助阵!快速通道分为新服通道...倩女幽魂2 进入专区>> 游戏类型:网络游戏 开发... 详情>>
12月3日WEGL微博杯赛事官方专题页正式上线,WEGL微博杯是由新浪游戏和竞综文化联合主办,上海耀宇文化传媒承办的PUBG赛事,在专题页中的海选战详情>>
12月3日WEGL微博杯赛事官方专题页正式上线,WEGL微博杯是由新浪游戏和竞综文化联合主办,上海耀宇文化传媒承办的PUBG赛事,在专题页中的海选战队人气投票环节深受玩家们的关注,短短几天的详情>>
小编为您搜罗的答案:那个要等主线剧情才能开启,现在是开不了的详情>>
2>隐世录手游在哪下载,隐世录手游下载地址分享。小伙伴们知道隐世录手游该在哪里下载吗?想必大都很感兴趣,下面一起来看看隐世录手游下载分享吧!详情>>
微软今天面向Fast通道用户发布了Windows10Build17738版本更新。通常情况下,微软不会选择在周二发布版本更新,但由于Windows10RedStone5分支的开发工作已经详情>>
利用通道抠图无非就是掌握以下三点:1,在蒙版中把你想要保留的部分涂成白色。2,在蒙版中把你不想要的部分涂成黑色。3,在蒙版中把想要变透明的部分涂成灰色。三步骤完成之后,你就可以将通道转为选区了。然后详情>>
PS通道抠图是一个比较常用的抠图方法,那么换背景我们最好的要求是光照角度一样,如果只是单纯的换一个图片,那么人物会显得突兀。第一步打开我们的照片,CTRL+J复制一层第二步点击通道,选择一个背景与人详情>>