代码改变世界

移动游戏的性能优化 | 贴图压缩篇

2024-06-05 12:19  kk20161206  阅读(312)  评论(0编辑  收藏  举报

在移动游戏应用中,贴图是带宽的主要来源之一,也会影响包体的 大小,例如,一张2048x2048 RGBA贴图,存储是16M,64张就有1G。有很多的贴图压缩技术能降低贴图大小,例如JPEG、PNG,它们有很好的压缩率和压缩品质,但是必需解压整张贴图,才能读取贴图上的像素值, 不支持随机读取。GPU渲染时,如下图所示,渲染两个邻居的三角面片,像素间的着色是完全独立的,只需要贴图上的局部块,而jpeg这些压缩技术无法支持这种类型的贴图读取。

 

GPU硬件层面支持贴图压缩算法必需具备如下4个基础要求:

 

● 支持随机读取

● 硬件解压效率高

● 较高的压缩比

● 压缩品质还行

 

压缩码率的单位,1 bpp = 1 bit per pixel,表示一个像素的存储单位,4bpp就表示一个像素按照4bit存储。

 

贴图压缩算法的核心思路,就是对贴图分块压缩,例如4x4的块,小块压缩也能提高GPU缓存的命中率,移动平台支持的有损压缩格式有:

 

● PowerVR Texture Compression,PVRTC系列

● Ericsson Texture Compression,ETC系列

● Adaptive Scalable Texture Compression,ASTC

 

pvrtc是面向powervr/ios设备,包括pvrtc、pvrtc2等。pvrtc2是pvrtc的升级版本,支持非2的整次幂,支持4bpp和2bpp两种码率。

 

etc是面向android设备,包括etc1、etc2、eac。etc1只支持RGB,兼容es2.0,码率是4bpp。etc2是etc1的升级版本,需要es3.0以上,支持RGB/RGBA。RGB码率是4bpp,RGBA码率是8bpp,还支持RGB + 1bit A 4bpp的压缩,当然只适用镂空图。eac扩展了etc2所能支持的格式,包括r11(4bpp)和rg11(8bpp)。

 

astc是面向移动全平台设备,由ARM和AMD联合开发,于2012年发布,后被Khronos作为一个标准特性。astc是一个完全开放的、免费的贴图格式,也是当前移动平台最好的贴图压缩技术。

 

2015年上线的手游,需要重点支持ES2.0的设备,然而etc1又不支持RGBA,那时的贴图会拆分成上半部分和下半部分,上半部分支持RGB,下半部分支持A,有一条基础的制作准则是贴图必需是2的整数次幂。还记得,当年为了测试打包模块,我还特地买了Texture Packer。

 

到了2019年,中高档设备已经能逐步支持astc压缩,正好处于过渡期,我们不能彻底放弃etc2,但是又想享受astc的收益。对于品质而言,astc 6x6 3.56bpp的效果比etc2的品质高,我们当年的产品做了一个决策是同时存储etc2 + astc的贴图资源,astc正常压缩,etc2尺寸降一半打进包内。做个简单的分析,假设RGB和RGBA的贴图占比为1:1,分两种情况:

 

● etc2,8 + 4 = 12bpp

● astc + etc2,(4 + 4) + (4 + 8) / 4 = 11bpp

 

从理论层面上,这种贴图策略,提高了中高档设备的品质,包体还降低了;从结果上看,当年那个产品的包体确实降低了。

 

时间到了2021年,从网上搜索到的资料,不支持astc的设备是1.5%,公司内部也认为不支持astc的设备占比很低,astc压缩已经是大势所趋。在2021年初,我们产品就彻底转向astc压缩格式,并落实它在游戏中的应用策略,UE4对astc的应用支持还是比较落后的。

 

现在移动平台的游戏,基本只考虑astc了,etc和pvrtc都成为了历史。官方对astc格式做了比较详细的介绍,参考“[Adaptive Scalable Texture Compression]”

(https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/ASTC_User_Guide_102162_0001_01.pdf?revision=2e4b1fcd-ed85-46c8-89da-397b7ab3a1bc)

 

相比于别的贴图压缩格式,astc有几个显著的优势:

 

● 自由选择需要压缩的颜色通道,可以支持RGB、RGBA、R等;

● 有更丰富的码率选择,最高的压缩码率是0.89bpp,最低的压缩码率是8bpp;

● 能支持更高级的贴图格式,例如3D贴图、HDR贴图;

● 在相同码率下,贴图的压缩品质更高。

 

对于游戏产品的应用而言,我们并不关心astc压缩算法的底层原理,我们更关注它有什么特性、能怎么用,这也是我接下来阐述的重点。

 

astc以128bit作为一个基础块进行压缩,可以自由选择合适的块大小,如下图所示,4x4块的码率就是128/(4*4)=8bpp,这张表很重要。块越小,码率越大,贴图品质越高。特别强调提,只有块的大小影响压缩后贴图的大小,被压缩贴图的内容/格式不影响最终的存储,例如,1024x1024的RGB和RGBA贴图,经过4x4压缩后,存储都是1M。相反,由于RGB和RGBA贴图的信息熵是不一样的,那么在压缩品质上RGB会比RGBA高。

 

astc不仅支持LDR,而且支持hdr、3D贴图。从实际应用而言,还有很多硬件设备不支持HDR压缩格式,导致astc HDR应用受限,我们产品中应用astc的HDR压缩,后面会介绍一个替代方案。

 

astc给每个纹素的颜色分配一个梯度值,每个压缩块,只需要存储两个端点的梯度值和每个纹素的加权值即可,如下图所示,解压缩的话只要将两个端点与加权值进行插值计算即可。

 
有时候,一个分区(Partition)无法满足要求,就需要多个分区,那么存储的数据就还包括一个索引值。

 

这个技术的内核是,压缩依赖整个块内颜色之间的梯度变化。它意味着什么呢?贴图像素的差异性,会影响最终的压缩品质。举个例子,一张贴图RGB,RG是有渐变规律的颜色,B是一个噪点,受到B通道颜色的影响,这张RGB贴图的压缩品质会很差。相反,一张视觉渐变平缓的贴图,压缩品质会很高,例如,lightmap贴图。

 

astc支持双平面模式(Dual-plane weights),一个像素有两个独立的加权值,通常RGB作为一组加权值,A作为另外一组加权值。这个技术的内核是,RGB和A之间的相关性会低一些,但不是没有相关性。它意味着什么呢?RGBA贴图A通道的压缩品质是最高的,在组织贴图的功能通道时,可以将重要度高的贴图数据放到A通道;法线贴图可以存储两个通道,RGB作为X,A作为Y,这种方式的压缩品质最高,也是官方推荐的。

编码器选择

以虚幻官方的4.24版本为例,支持两套编码器:

 

● intel的ispc,支持mac/Windows,版本是1.7.0;

● arm的astcenc,支持linux/mac/windows,版本是1.3。

 

从两个方面来分析编码器的优缺点:

 

● 效率,判断编码器的压缩快慢,直接影响打包的效率;

● 品质,判断压缩出的贴图品质,用PSNR度量(Peak Signal To Noise Ratio,峰值信噪比,也不是一个完美的度量标准,但是够用),单位是dB,值越大,品质越高。

 

以6x6压缩为例,ispc的压缩效率比astcenc 1.x快了近44倍,参见“Fast ISPC Texture Compressor - Update”。但是,arm对它们的编码器持续优化升级,到2.x之后,已经不存在如此大的效率差异。以arm于2020年公布的数据为例,参见“ASTC codecs compared”来说明。

 

效率测试,以astcenc -fast编码模式为基准:

 

● 4x4,ispc平均是1.32x,medium是0.18x;

● 6x6,ispc平均是1.53x;

● 8x8,ispc平均是1.63x;

 

ispc的效率最多比astcenc -fast快一倍,显著优于-medium,-thorough模式。

 

 

 

测试,以astcenc -thorough编码模式为基础:

 

● 4x4,ispc比-fast差0.2dB,比-medium差1dB,比-thorough差1.4dB

● 6x6,ispc比-fast好0.2dB,比-medium差0.5dB,比-thorough差0.7dB

● 8x8,ispc比-faast好0.3dB,比-medium差0.6dB,比-thorough差0.9dB

 

 

 dB是一个对数单位,从视觉的角度而言,肉眼难以识别0.25dB的差异,1.0dB的差异是很显著的,肉眼是可以观测到的,如下图所示,留意鹦鹉头部绿色区域。游戏内的贴图经过渲染,能将差异放大,在游戏画面上的表现就是糊或马赛克。对于一些功能贴图,例如法线贴图,astcenc -thorough的压缩品质会显著优于ispc。

 

综上,可以得出两条结论:

 

● 效率,ispc比astcenc 2.x -fast快,上限是4x,已经不是44x的差异了,但是-thorough比-fast慢了非常;

● 品质,ispc比astcenc -thorough差1dB,法线贴图的差异会更显著。

 

压缩效率是离线开销,如果通过离线开销,置换手游运行的贴图品质,也是一件很有价值的事情,至此我们还有两个疑问需要解答:

 

● fast和thorough的品质差异是多少?

● 不同压缩块的品质差异是多少?

 

从官网下载了24张贴图进行测试,基于arm的astcenc 2.5进行测试。

 

 测试-fast和-thorough差异,低的平均是0.2dB,高的话能达到1.4dB,平均差异在1dB左右。

 

测试不同压缩块thorough模式下,品质的差异,以10x10为基准:

 

● 10x5和8x6,10x6和8x8两组数据的品质差异不大,两者的存储也不大;

● 最低8x8与最高4x4的PSNR差异在12dB,8x8、6x6、5x5、4x4之间的差异平均在3dB;

● 8x8与8x6之间有两个子档8x6和8x5,6x6与5x5、5x5与4x4之间有一个子档位。

 

平均1dB的差异,接近一个子档位的差异。打个比方,用fast + 8x5(3.2bpp)压缩的贴图品质跟用thorough + 8x6(2.67bpp)一样,再换句话说,就是原来需要320M,用thorough压缩只需要267M。

 

此外,ispc功能支持有限:

 

● 有限的压缩块选择,例如4x4、5x5、6x6、8x8、10x10;

● 只支持2D贴图,不支持HDR贴图;

● 缺少精细化的调参;

● 等等。

 

综上,我们采用的技术策略是:

 

● 切换至arm的astcenc编码器,升级编码器至4.7;(3年前,astcenc是2.5,最新官方的版本是4.7,进一步提升了效率和品质)

● 扩展档位,支持了除10x5、10x6以外的所有档位,包括4x4、5x4、5x5、6x5、6x6、8x5、8x6、8x8、10x10、12x10、12x12,方便后续做更精细的贴图管理;

 编码命令

 

astcenc支持5种模式,需要的运行时间越多,压缩出来的品质越好。exhaustive会显著提高运行时的压缩时间,比起thorough,只会在边缘处有一定的改善,选择thorough即可。本地测试的时候,可以将速度调来veryfast。

 

● -veryfast

● -fast

● -medium

● -thorough

● -exhaustive

 

引擎侧需要根据贴图是否是sRGB,来选择-cs还是-cl命令。

 

此外,astcenc提供了更丰富的参数定制化功能,例如:

 

● -perceptual

The codec should optimize perceptual error, instead of direct RMS error. This aims to improves perceived image quality, but typically lowers the measured PSNR score. Perceptual methods are currently only available for normal maps and RGB color data.

 

● -cw <red><green><blue><alpha>,

Assign an additional weight scaling to each color component, allowing the components to be treated differently in terms of error significance. Set values above 1 to increase a component's significance, and values below 1 to decrease it. Set to 0 to exclude a component from error computation.

 

● -pp-normalize

Run a preprocess over the image that forces normal vectors to be unit length. Preprocessing applies before any codec encoding swizzle, so normal data must be in the RGB components in the source image.

 

● 等等

 

那么,请思考一个问题:我们能否根据游戏产品的贴图特点,科学地定制最合适的编码命令?对于常规的RGB和RGBA贴图,我们就用普通的命令即可。

 

● RGB贴图,astcenc-avx2 -cs example.png example.astc 8x8 -thorough -cw 1 1 1 0

● RGBA贴图,astcenc-avx2.exe -cs example.png example.astc 8x8 -thorough -cw 1 1 1 1

 

对于一些特殊贴图,例如法线、灰度图等,我们可以通过实验来做一些测试论证,测试的基本流程是:

 

1)选择合适的测试贴图;

2)构造编码命令,将测试贴图压缩成astc格式;

3)解压缩astc贴图,将它与原始贴图比对,生成psnr数据;

1 。法线贴图

严格来说,不能简单的通过psnr指标来评判法线贴图的压缩品质,但它是最容易获取的性能指标。

 

在手机游戏中,为了减少采样贴图数,会将法线存储在RG两通道,粗糙度存储在B通道中,简单测试了这种存储策略的压缩品质。对于astc而言,RGB是作为一个整体,法线的品质严重依赖粗糙度,粗糙度的渐变越复杂,法线品质越低,提高码率不一定能提高贴图品质,如下图所示。法线是最重要的一张贴图,它的压缩品质不高的话,在游戏内的表现,就是画面不够清晰,甚至有马赛克。

 

测试命令:astcenc-avx2.exe -cl example.png example.astc 6x6 -thorough -cw 1 1 1 0

 

那么,针对独立的法线贴图,按照什么命令压缩,带来的品质更高呢?方案一是UE原生的压缩命令,方案二是astc官方推荐方案。

 

方案一,astcenc-avx2 -cl example.png example.astc 8x8 -thorough -esw rg00 -ch 1 1 0 0 -oplimit 1000 -mincorrel 0.99 -dblimit 60 -b 2.5 -v 3 1 1 0 50 0 -va 1 1 0 50

方案二, astcenc-avx2.exe -cl example.png example.astc 8x8 -thorough -normal -pp-normalize -perceptual -esw rrrg

 

我们随机选择6张法线贴图,测试5x5、6x5、6x6、8x5、8x6、8x8分档下的性能数据,如下所示。方案一与方案二相差1dB~2dB左右,相当于差了一个小档位的。我觉得最大的原因是astc支持双平面模式,RGB存储X,A存储Y的压缩存储最适合astc,配套的,需要改造引擎支持法线的RA反解法线贴图。是否可以自己尝试定制系数提高法线的压缩品质呢?我的理解是,可能花大量时间基础上,在有限的几个测试用例下找到一组psnr更高的指标,但是它是否有普适性呢?astcenc的开发组对astc压缩的理解远比我们深刻,接受它们推荐的命令也是我觉得最优的技术选择。

 综合切换编码器,升级为thorough编码模式的收益,法线贴图的压缩能获取2~3dB的品质提升。什么概念呢?就是现在8x8的法线压缩品质与原来6x6一样,8x8的码率是2bpp,6x6的码率是3.56,相当于相同品质下法线的存储能降低一半。

 

灰度贴图

由于astc压缩算法的特殊性,需要重新考虑灰度贴图最优的编码命令:

 

方案一,作为RGB进行压缩,astcenc-avx2.exe -cl example.png example.astc 8x8 -thorough -cw 1 1 1 0 -esw rrr1

方案二,作为RGBA进行压缩,astcenc-avx2.exe -cl example.png example.astc 8x8 -thorough -cw 1 1 1 1 -esw rrr1

方案三,只对R通道进行压缩,astcenc-avx2.exe -cl example.png example.astc 8x8 -thorough -cw 1 0 0 0 -esw rrr1

 

经过测试发现,方案一的压缩品质是最高的。

 

 

功能贴图

在实际应用中,我们通常会将不同功能通道的数据合成一张贴图,例如粗糙度+金属度+AO的功能贴图,这三组不同的成分对表现效果的影响也不尽相同。粗糙度影响最大,AO其次,金属度最低,甚至于很多产品没有金属度贴图。于是,我就有了一个想法:贴图压缩时,不同通道有不同的加权值,确保影响大的通道品质更高。

 

方案一,常规压缩,astcenc-avx2.exe -cl example.png example.astc 8x8 -thorough -mask -ch 1 1 1 0

方案二,加权压缩,三通道的权重分别是4、2、1,astcenc-avx2.exe -cl example.png example.astc 8x8 -thorough -mask -cw 4 2 1 0

 

基本符合预期,提高了粗糙度的品质,同时AO和金属度的品质都有所下降。

 

 

RGBM贴图

现在的移动设备对astc hdr贴图的支持还不够完善,那就意味着无法直接使用hdr贴图了,但是在产品中,有一些特殊的应用需要比较大的HDR贴图,如果不进行压缩的话,手机平台是无法接受的一张几十M的贴图的。例如,天空球上需要一张1024x2048的HDR贴图,不考虑mip的话,就有24M。

 

一种优化做法是,对hdr进行rgbm编码,能降低一部分贴图大小。

 

float4 RGBMEncode(float3 Color, float MaxValue)

{

    Color *= 1.0 / MaxValue;

 

    float4 rgbm;

    rgbm.a = saturate(max(max(Color.r, Color.g), max(Color.b, 1e-6)));

    rgbm.a = ceil(rgbm.a * 255.0) / 255.0;

    rgbm.rgb = Color / rgbm.a;

 return rgbm;

}

 

float3 RGBMDecode( float4 rgbm, float MaxValue )

{

return rgbm.rgb * (rgbm.a * MaxValue);

}

 

这张贴图经过rgbm编码后,能否用astc进行压缩呢?我简单用ibl反射贴图做了一个测试,4x4 + thorough模式,发现压缩品质惨不忍睹。

 

好消息是,astcenc编码器支持了-rgbm模式,表示编码器知道这张贴图是rgbm压缩,会按照适合这种格式的方式进行编码,生成astc贴图。这张astc贴图没有任何的特殊性,不需要任何的硬件扩展,gpu采样这张贴图后,需要在shader中反解出hdr数据。

 

● -rgbm <max>

The input texture is an RGBM encoded texture, storing values HDR values between 0 andin an LDR container format with a shared multiplier. Shaders reconstruct the HDR value as: vec3 hdr_value = tex.rgb * tex.a * max. The compression behavior of the ASTC format for RGBM data requires that the user's RGBM encoding preprocess keeps values of M above a lower threshold to avoid them quantizing to zero during compression. We recommend trying 16/255 or 32/255

 

选择压缩命令如下所示,发现压缩品质太顶了。

 

astcenc-avx2.exe -cl example.png example.astc 8x8 -rgbm 16.0

 

RGBM压缩模式,适用于一些HDR贴图,可以显著降低贴图存储,例如一张2048x2048的HDR贴图,存储是96M(不考虑mip),经过astc 6x6压缩的话,存储是2M,品质还很高。

 

它不适用于IBL这种特殊功能贴图的压缩,主要两个原因:

 

● 收益很极,一个反射体环境贴图的尺寸是64x64x6,它的存储0.0208M,100个反射体的存储也就2M,压缩没啥意思;

● 品质受损,IBL每一级是经过卷积计算出来的,近景粗糙高的模型也会用到低mip,低mip贴图的rgbm压缩品质很差,如下图所示:

 

 

小结

总结下不同类型的贴图的压缩命令:

 

● RGB贴图

astcenc-avx2.exe -cl example.png example.astc 8x8 -thorough -ch 1 1 1 0

 

● RGBA贴图

astcenc-avx2.exe -cl example.png example.astc 8x8 -thorough -cw 1 1 1 1

 

● 法线贴图

astcenc-avx2.exe -cl example.png example.astc 8x8 -thorough -normal -pp-normalize -perceptual -esw rrrg

 

● 灰度贴图

astcenc-avx2.exe -cl example.png example.astc 8x8 -thorough -cw 1 1 1 0 -esw rrr1

 

● Roughness + AO + Metallic类型的功能贴图

astcenc-avx2.exe -cl example.png example.astc 8x8 -thorough -mask -cw 4 2 1 0

 

● RGBM贴图

astcenc-avx2.exe -cl example.png example.astc 8x8 -rgbm 16.0

 

 应用策略

 

我们有一个美好的愿景,希望针对不同贴图特点,通过科学地数据测试,选择合理的码率来压缩。那么,就需要去确定测试指标来论证合理性,数据指标有两个:

 

● 客观指标,PSNR等;

● 主观指标,画面糊不糊、有没有马赛克等等;

 

一种基于客观指标的做法,就是自适应策略:基于一个PSNR数值指标,选择不同的码率压缩对贴图进行压缩,自适应的选择最优码率。这种做法,有显著的缺陷:

 

● 效率问题,贴图压缩的时间是按照h为单位的,这会极大提高包体构建时间;

● 稳定性问题,贴图的修改会导致psnr变化,基于psnr选择不同的码率,使得贴图在手游上的表现不稳定;

● 指标问题,psnr可以作为度量贴图品质的一个指标,但是不是唯一指标,换句话说就是,psnr数据好,不一样表现效果就好;

 

对于游戏产品而言,我们综合美术表现和技术性能,采用贪心策略来确定合适的码率。对单一贴图的压缩品质测试,得到的psnr数据无法推导到游戏产品设计的贴图类型,得到的品质数据也是偏主观,最终还是要以手游内的品质为准,那么我们能做哪些工作呢?

 

● 引擎底层,可以提供一套定制策略,支持不同贴图的码率管理;

● 制作层面,推荐更适合astc编码特性的压缩策略;

 

 

技术层面

 

单一的码率是无法满足游戏产品各种不同的贴图特点,码率选择高了是浪费,选择低了品质不足,通用的方法就是分组管理:

 

● 角色材质

● 场景材质

● 特效材质

● UI材质

● 烘焙贴图

● 等等

 

虚幻引擎的贴图属性中有一个Texture Group,我们就可以基于Texture Group属性,配置不同的码率。影响贴图码率选择的因素有:

 

● 用途,例如角色、场景等,场景贴图的压缩品质通常低于角色材质等;

● 类型,例如法线、基色等,法线贴图对画质影响比较大,也需要更高的码率;

● 信息熵,例如RGB、RGBA等,RGBA要求的码率会比RGB更高;

 

通过引擎的贴图分组,区分用途和贴图类型,同一个贴图分组可以支持RGB和RGBA两种格式。由于拓宽了astc格式,支持了除10x5、10x6以外的所有压缩块,容易更精细化的管理贴图压缩存储,例如一个分组的配置:

 

+TextureLODGroups=(Group=TEXTUREGROUP_World,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=linear,MipFilter=linear,MipGenSettings=TMGS_SimpleAverage,AstcRGB=TCQ_ASTC_8x8,AstcRGBA=TCQ_ASTC_8x6)

 

+TextureLODGroups=(Group=TEXTUREGROUP_WorldNormalMap,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=linear,MipFilter=linear,MipGenSettings=TMGS_SimpleAverage,AstcRGB=TCQ_ASTC_8x6,AstcRGBA=TCQ_ASTC_8x6)

 

+TextureLODGroups=(Group=TEXTUREGROUP_WorldSpecular,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=linear,MipFilter=linear,MipGenSettings=TMGS_SimpleAverage,AstcRGB=TCQ_ASTC_8x8,AstcRGBA=TCQ_ASTC_8x6)

 

贴图分组提供了通用的管理策略,不能满足产品各种特殊的定制化需求,从两个方面来分析:

 

1)贴图通道组织的复杂性,材质系统是很复杂的,大量材质贴图的功能通道是定制的;

2)贴图的压缩品质差异性大,由于贴图的各通道是根据需求定制的,贴图存储的内容会影响整体的压缩品质,例如一张贴图的RGB是普通的颜色,A通道是噪点贴图,这张贴图的压缩品质会很低,那么就需要能独立调整单张贴图码率的制作;

 

如果用的是材质实例,只需要修改贴图属性即可。如果用的是一套虚拟材质系统,贴图是在引擎侧生成的,就需要在虚拟材质模板和虚拟材质实例上完善相应的定制化机制。

 

 

制作层面

 

贴图信息熵影响压缩品质。码率是影响贴图存储大小的唯一因素,相同码率下,RGB的压缩品质会显著高于RGBA,视觉表现就是RGB看不出噪点,但是RGBA能看到显著噪点,换句话说,RGB和RGBA用相同的码率是不合理

 

类似的,单通道的灰度当成RGB贴图也是很大的浪费,经过测试,可以认为10x10(1.28bpp)灰度图的压缩品质与6x6(3.56bpp)RGB贴图的压缩品质相当,但是存储相差几倍。

 

材质的贴图通道要如何组织才能达到更高的品质、更好的性能呢?需要了解astc贴图压缩的特点,简单总结下:

 

- 1)只有码率会影响存储大小,与贴图类型、内容等没有任何关系,例如选择了6x6压缩,那么每个像素的存储就是3.56bit,单位是bit,不是byte;

- 2)压缩块的选择越大,存储越小,压缩品质越差,即4x4的品质最高,12x12的品质最差,记住这张排序图:

 

3)相同码率条件下,RGB品质更高,因此RGB和RGBA可以选择不同的码率,例如RGB是8x8,那么RGBA可以是8x6,提高一个小档;

4)RGBA的存储结构,A通道的压缩品质最高;

5)法线独立压缩的品质最高,例如6x6就显得很浪费了;

6)对于粗糙度+AO+金属度贴图,可以用加权压缩模式;

7)各通道自由组织的功能贴图,贴图内容的规律性会影响整体的压缩品质,例如一张贴图的RGB是普通的颜色,A通道是噪点贴图,这类贴图的压缩品质会很低;

 

案例1,标准的PBR材质,包括BaseColor、Normal、Roughness、Metallic、AO,有几种不同的贴图组织方式:

 

方案一,BaseColor + Roughness 8x6,Normal + Metallic + AO 6x6

方案二,BaseColor 8x8,Normal 8x6,Roughness + AO + Metallic 8x8(尺寸降低一半)

 

存储分析,方案一是2.67 + 2.56 = 5.23 bpp,方案二是2.0 + 2.67 + 2.0 * 0.25 = 5.17 bpp,差异不大;品质层面,方案二的品质远远好于方案一;实时开销,方案二会多一次贴图数的采样。

 

案例2,金属对光照的影响比较大,有比较多的游戏产品只区分金属和非金属,缺少金属度贴图,有两种方案:

 

方案一,BaseColor + Roughness,Normal + AO

方案二,BaseColor,Normal + AO + Roughness

 

两者的贴图数相同,需要考虑几个因素:

 

● 法线对表现的影响更大;

● 粗糙度贴图的特点就是细节复杂,会增加贴图的颜色梯度变化,降低贴图的压缩品质。

 

综合分析,方案一品质会更高。

 

案例3,现在的游戏对材质的要求越来越高,希望材质是多层混合,减少贴图制作。为了降低采样的贴图数,我们不得不用上Normal + Roughness + Mask的组合,往往这类材质在移动平台最可能出现精度问题,表现就是马赛克,有时候通过提高存储并不能有效提高品质。

 

案例4,烘焙贴图,移动平台的烘焙贴图通常会存储Color + Shadow/AO,烘焙贴图存储的数据是低频的GI信息,颜色过渡较平缓,astc的压缩品质会很高,通常8x8就可以满足品质要求了。

 

我也做了一些简单的测试,虚幻原生的PC压缩效果比astc 8x8的压缩品质差,8x8和6x6的品质差异不显著。为了提高UE4 PC预览效果,PC默认的压缩格式可以调整为BC6/BC7。

 

 

 

我们项目的几种策略:

1. Rough2BaseA_M2NormalB_AO2NormalA

2. Rough2BaseA_AO2NormalA

3. Rough2BaseA_M2NormalA

 

原图orm,AO在r通道,但是贴图格式是bgra,所以索引是2.

r,粗糙度在g,索引为1

m,在b,索引为0.

 

 

 bgra格式编码的: