Unity中纹理格式探究

Unity中纹理格式探究

1)Unity项目中纹理格式的使用探究
2)Post Processing生成的RenderTexture过大
3)背景音乐的音频文件的格式设置
4)如何避免新版本下的GC
5)关于NGUI上的RigidBody设置


这是第142篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。

UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)


资源

关于Unity中使用的纹理格式问题,自己查了一些资源,有了一些大概的认知,但是希望能有比较完整、有理有据的依据。如果已有整理好的文章求科普!目前从各方面渠道得到的大致结论有:

  • ETC2:安卓推荐格式,支持Alpha通道
  • PVRTC:iOS推荐格式?支持Alpha但是效果很差
  • ASTC:效果很好,iOS推荐格式,不支持iPhone5s
  • RGB24/RGBA32:不推荐使用,尽可能用ETC2/PVRTC/ASTC,如果不行用Dither(UWA建议)
  • Alpha8:Mali GPU的机型不支持
    产生了以下疑问:
  • 以上结论是否正确,有没有什么补充?目前使用来说感觉PVRTC的尺寸限制比较大(正方形+长宽2的幂)
  • 大家在场景、角色、UI不同的用途来说一般都是如何选择的?目前我们项目里感觉UI用PVRTC美术接受不了(ASTC暂时还没决定用),Lightmap用ETC2在某些地方放大疵边比较明显,有什么好的办法吗?
  • 尺寸大家一般是如何定的?比如1080P的全屏Loading图,一般定多少?我看王者荣耀的Loading图画质很差
  • Mipmap一般要不要开呢?如果开的话,其中的一些设置怎么设比较合理?

A1:关于ASTC的支持率,参考贾伟昊的回答。
https://answer.uwa4d.com/question/5a6700517daacf4c7ff04918
可以考虑在iOS上用起来,但是要放弃一些机型。安卓上建议使用ETC2,搭配Unity的Crunched算法,效果更佳。RGB24/RGBA32确实不建议使用,主要是会占用显存带宽,但是效果确实好。Dither是可以用,但是对Scale9和渐变不友好。
UI的Mipmap不要开,UI不会发生Mipmapping的情况,除非你设计的纹理尺寸比实际用到的要大很多。
模型的纹理资源的Mipmap一般是要开的。RTR第三版 18.3.1提到Mipmap可以提高纹理Cache连续性,即提升Cache的命中率,也提升了纹理采样的速度。另外开了Mipmap,可以在Mipmap level之间进行三线性滤波(当然这个是不建议开的),可以使纹理放大缩小的时候,看起来质量更好。因为在生成Mipmap的时候,Unity可以选择滤波算法,所以即使不开三线性滤波,在对应的Mipmap level上采样,也比在原来的大尺寸的纹理上采样效果要好一些。
感谢凯奥斯@UWA问答社区提供了回答

A2:凯奥斯已经回复得很全面了,想到的内容就补充一下好了。
1)了解一下各种压缩格式对应的设备OpenGL ES版本限制,这样方便你面对问题的时候做取舍,常规的建议终究只是立足于经验和项目的建议,个人根据自己项目需求的判断更加适用。
2)类似PVRTC的限制,和压缩方式有关,也和GPU采样效率有关。所以即便选择没有限制的压缩格式,甚至不压缩,PVRTC的限制都最好保持长宽为2的幂。
3)UI用PVRTC的确难以接受,主要还是Alpha通道的问题。大型项目可以考虑ASTC,另外的思路就是拆分Alpha通道、白名单内的贴图采用不压缩或者Alpha通道拆分的方式。
4)我们Loading图一般是对应的设备上的压缩格式,比如安卓ETC2、iOS上ASTC,其实Loading图一般不透明,PVRTC也够用了。尺寸按照UI需求一般是和设计分辨率一致。这个也完全看缩小之后的效果UI是否满意,Loading图注意及时卸载,只增加峰值,不常驻占用,内存影响不大,包体方面一般没这么敏感。
5)除了UI不用开Mipmap之外,比如一些2.5D的固定视角游戏有时候也不开,目的是追求清晰度;另外有些特殊的贴图也可以不开,比如染色用的Mask通道图等等,我们一些面部的贴图美术也要求关闭掉,这些从效果出发都可以满足,不一定完全按照固定的规则执行。
感谢贾伟昊@UWA问答社区提供了回答

A3:之前整理过项目里面几种纹理格式的特点,其实题主大部分也都提到了,就作为一个补充贴出来吧。其中画质是我个人的肉眼感觉,没有绝对的数据比较,仅供参考。

请输入图片描述
感谢喵小逗@UWA问答社区提供了回答

A4:能不能压缩,也需要考虑美术的感受。
最近手上的游戏2D序列帧用得比较多, 此时使用ETC2和PVRTC因为压缩的原因,会产生闪的问题。使用拆Alpha通道的方式可以一定程度上避免,特别是对于带Alpha通道的图,ETC2质量低的原因大半在于对Alpha的压缩。
ASTC的质量是明显好于PVRTC的,iPhone上唯一的问题是iPhone 5s的支持。我们的方案是,如果机型不支持ASTC,会额外准备一份低质量的PVRTC的资源,尺寸是原图的一半,而设计的主要目的是解决内存问题,顺带解决iPhone 5s的压缩问题。
感谢史亚征@UWA问答社区提供了回答

该问答来自UWA问答社区,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c1a1bde4e577c207402d2c5


后处理

Q:使用了Unity的Post Processing功能,但发现它建立了非常大的Render Texture,请问这有什么办法可以解决吗?

UWA:大多数Post Processing都是需要获取当前屏幕内容的,所以确实不可避免地会生成和屏幕分辨率相同(或者成比例)的RenderTexture,所以建议先整理目前项目里每个Post Processing所用到的RenderTexture分辨率和数量,然后针对性地修改,比如:Bloom可以把DownSample数降低,从而减少Blit的次数和RenderTexture的数量等等。

A2:这种后处理操作,一般会统一写到一起,挂到maincame上进行统一操作,并且使用同一个shader进行渲染,达到统一管理,减少开销的作用。

感谢郑骁@UWA问答社区提供了回答

该问答来自UWA问答社区,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c1b8de9bf256b207515162c


音频

Q:我在UWA的报告里看到建议用Streaming的方式读取音频。
请输入图片描述
想问一下关于音频格式,有优化角度比较全的建议吗?之前项目里的设置大概是这样子的,合适吗?


大家常见的做法是怎样的呢?有没有一个相对合理的经验值,比如10s的音效大小在100KB这样的参考值?

A1:WAV 适用于较短的音乐文件可用作游戏打斗音效;
MP3 适用于较长的音乐文件可用作游戏背景音乐;
取消勾选Preload Audio Data选项,勾选安卓环境下的Override for Andriod选项,并设置Load Type为Streaming;
这是比较通用的加载及音频设置。
感谢郑骁@UWA问答社区提供了回答

A2:补充一下。其实这个东西还是根据自己项目的实际情况,考虑包体大小、内存大小、加载速度、运行压力等因素进行设置。
背景音乐,MP3格式比较好,原因也是因为通常背景音乐会比较大,包体会小些。较短的音乐选择WAV或者MP3都可以,各有优劣。MP3的优势就是包体小,WAV的优势是在Compressed in Memory和Vorbis选项下占用的内存会小些。
Load Type为Streaming其实CPU消耗还是比较高的,但是内存占用很小,所以根据自己的内存情况选择。举个例子,比如在战斗中频繁加载使用的是很短的音效,可能内存就不是瓶颈,这个时候更应该考虑的是CPU的压力,那么选择Decompressed On Load就更合适些。
另外,对一些不是即时播放的音乐,比如说背景音乐,建议勾选Load In BackGround。
感谢赵林@UWA问答社区提供了回答

该问答来自UWA问答社区,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c189a63bf256b207515158b


GC

Q:在Unity 2018.X以后都有,空场景下就会有这么多的GC.Alloc,请问能怎么避免呢?

A:升级到2018.3
https://issuetracker.unity3d.com/issues/renderpipelinemanager-dot-cleanuprenderpipeline-increasing-alocated-memory-every-20-seconds
Fixed in Unity 2018.3

请输入图片描述

感谢贾伟昊@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c175ab84e577c207402d25c


NGUI

Q:NGUI会在UIPanel上挂一个RigidBody,Google了下说是可以优化性能,之前团队里也一直是这么做的。但最近听到一个说法是在Unity 5.x之后就不需要再加这个RigidBody了。求教正确说法,以及现在到底还要不要加这个RigidBody呢?

UWA:Unity 4.x下移动静态碰撞体有额外开销,所以NGUI会默认挂上RigidBody,转成动态碰撞体,优化这个问题。但5.x上就没有这个问题了,所以可以把NGUI挂RigidBody的逻辑给去了。
该问答由UWA提供,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c0ddcd428c4e32cba319326

今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
官方技术QQ群:793972859(原群已满员)

封面图来源:Vapor(使用Unity实现体积雾效果)
https://lab.uwa4d.com/lab/5b5ccd7ed7f10a201fe95828