纹理的外部格式对其内存的影响

纹理的外部格式对其内存的影响

1)纹理的外部格式对其内存的影响
​2)更换Mac平台后项目中的部分DLL失效
3)打Shader包的时候是否需要将cginc打进去
4)内置Standard的替代方案


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

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

Texture

Q:原来一个Prefab用到的图是16MB,4096*4096像素,然后用PS压缩了一下变成600KB(分辨率不变)。打AssetBundle测试,除了AssetBundle的大小由27MB变成了20MB,在内存中的Texture 2D都是一样的。因为在Unity设置的压缩格式是一样的,所以在Unity里面看到的内存也是一样大的,难道Unity里面的图片大小跟原图大小没关系?原图大小用PS压缩/不压缩除了AssetBundle收益,在不改Unity中图片压缩格式的前提下,内存就没收益了吗?

我猜想是不是Unity读取的原图,在运行时都是根据原图,然后根据Unity里面设置的压缩格式自己在内存中是一份新的图,就跟原图没什么关系了?

A1:图片导入Unity,就会按设置的格式和压缩变成Unity自己的格式,此时的内存大小就和图片原始大小无关了。这时要到Inspector里的下方看图片的压缩格式和内存大小。猜想是Unity把图片导入时,自动转换了一份自己的格式存储到了Library里,所以真正加载显示的就不是原始那张图片了。

感谢林健@UWA问答社区提供了回答

A2:首先我们要明确一个概念,我们在电脑上看到的png格式或者jpg格式的图片,png / jpg只是这张图片的容器,它们是经过相对应的压缩算法将原图每个像素点信息转换为用另一种数据格式表示,以此达到压缩目的,减少图片文件大小。

当Unity将这张图片加载进内存时,这些文件会被转换为特定的格式,调取速度更快,占据内存更少,比如ASTC_6X6等。

纹理加载进内存后,大小计算公式如下:
纹理内存大小(字节)=纹理宽度 x 纹理高度 x 像素字节
像素字节 = 像素通道数(R/G/B/A)x 通道大小(1字节/半字节)

感谢马三小伙儿@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/6121f7678f8c8342417bb23e


Editor

Q:项目需要开发Mac OSX平台应用,换到苹果电脑之后sqlite3.dll和user32.dll失效了,在网上下了很多替换的都不行,其它的DLL都可以,请问如何兼容这两个DLL呢?

A:你的sqlite3.dll应该是只能应用于Windows平台,Mac上需要对应平台的Sqlite库。user32.dll这个很明显是个Windows平台的动态链接库,Mac上无法使用。

我又搜索了一下资料,发现在iOS、Mac上好像不需要额外地去导入原生的Sqlite库,它们有自带预编译好的Sqlite库。你所需要做的是:将Mono.Data.Sqlite.dll这个文件从引擎目录拷贝出来,放置在Plugins目录下。

具体可以参考这两篇教程:《Unity工具—Mono.Data.Sqlite 使用》

集成流程看这个:《Setup Database (SQLite) for Unity》

我按照上面的步骤做了一个Demo测试了一下,Windows和Mac上都可以正常的运行。

感谢马三小伙儿@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/611ddf2f8f8c834241760223


Shader

Q:本来项目中用的是内置的Standard,为了减少变体的原因,将Built in的Shader包含cginc文件的全部放到本地。打Shader的时候,需要把引用到的cginc文件也打进Shader包内吗?看到有说其实cginc的代码片段被编译到了Shader中,按照这种说法不就应该只要打Shader就行,对应的cginc是否还需要打进去?

A1:不需要,打包时候Shader会编译成对应平台的Shader,已经自动将cginc的代码合并进来了。

感谢范世青@UWA问答社区提供了回答

A2:不需要的,举个例子,如下一个简单的CG,其中定义了vert和frag函数,及2个uniform和一个常量:

同时创建一个“Shader1”使用这个CG的vert&frag实现:

在Shader的Inspector面板选择对应平台编译,Shader的编译类似C++的编译,#include可以理解为将文件内容展开,编译完的结果如下,Vertex Program:

Fragment Program:

Shader打包就是编译的过程,所以不需要把CG/cginc等打包。

感谢羽飞@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/612058298f8c834241798199


Shader

Q:使用内置的Standard,一方面有变体,另一方面使用一次7MB内存,有没有比较不错的替换方案?也可以自己写一些漫反射、金属、高光等属性,想问一下有没有更好用的?

A1:首先,内置Shader在实际项目中的确不被推荐使用,因其Keyword导致变体非常多,最终Shader自身或ShaderLab的内存占用会比较高,这个统计受到Unity版本的影响。

该点可参考:《Shader内存统计与版本关系》

其实自己写Shader是最可控的方式了,可以根据自己的项目写一些有针对性的效果,如果只需要一些常规的效果,可以参考Standard Shader的源码,用一些Unity封装好的基于PBR光照模型的方法。

感谢翟孟飞@UWA问答社区提供了回答

A2:通过本地目录Editor\Data\CGIncludes中的cginc文件和官网下来的Built in Shader把你需要的效果都抽出来减少Shader的变种数量。打包的Shader和对应的cginc是自动打在一起的。

感谢萧小俊@UWA问答社区提供了回答

A3:不建议使用内置Shader,原因题主也写了。默认的Shader更多的是给到一个大而全的选择,比较适合快速做原型Demo。

实际项目开发中建议还是根据美术的实际需求自己从头来写,部分功能可以参考内置Shader的代码,这样既能满足美术需求,又能满足性能的要求。

感谢范君@UWA问答社区提供了回答

A4:这个Standard就是把以前的一些Built in的Shader融合在一起了,实现的效果确实是多了,但是也显得很臃肿,还是建议自己拆分定制不同的Shader,或者下载Built in里面的Shader。

感谢Lim@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/6119e3ca8f8c834241704766

20210824
更多精彩问题等你回答~

1.Vulkan API的性能及兼容性
2.Unity TMP字体方案如何选择
3.如何实现AAB包的增量更新

封面图来源于:ChromaPack
ChromaPack - Unity的有损纹理压缩插件。


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

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