zoukankan      html  css  js  c++  java
  • Uinty3D性能优化之贴图科普篇

    • 一、贴图和纹理

    • 图像文件格式和纹理格式的区别:

    常用的图像文件格式有BMP,TGA,GIF,JPG(有损不透明),PNG(无损透明)等;
    常用的纹理格式有R5G6B5,A4R4G4B4,A1R5G5B5,R8G8B8, A8R8G8B8等。

    • 文件格式

    图像为了存储信息而使用的对信息的特殊编码方式,它存储在磁盘中,或者内存中,但是并不能被GPU所识别,因为以向量计算见长的GPU对于这些复杂的计算无能为力。这些文件格式当被游戏读入后,还是需要经过CPU解压成R5G6B5,A4R4G4B4,A1R5G5B5,R8G8B8, A8R8G8B8等像素格式,再传送到GPU端进行使用。

    • 纹理格式

    是能被GPU所识别的像素格式,能被快速寻址并采样。
    所以在Unity中无论导入图片是什么格式,Unity都会转换成纹理格式,便于GPU读取使用。
    OpenGL ES 2.0支持以上提到的R5G6B5,A4R4G4B4,A1R5G5B5,R8G8B8,A8R8G8B8等纹理格式,其中R5G6B5,A4R4G4B4,A1R5G5B5每个像素占用2个字节(BYTE),R8G8B8每个像素占用3个字节,A8R8G8B8每个像素占用4个字节

    • 纹理压缩格式(硬件压缩格式)Hardware Accellerated Formats
    • DXT(PC)  ETC(Android)  PVRTC(IOS)

    把纹理进一步压缩(Texture Compression),不像png那样采用霍夫曼编码,而是针对GPU硬件的格式来压缩。

    如果GPU不支持当前压缩格式,Unity就会将纹理转换成RGB(A),会造成解压过程消耗内存中会保存两个纹理

    • 图片大小计算:

      一个像素占的字节 = 位数(bit)/ 8   因为一个字节8位

    一张图片占的内存大小 = 宽 * 高 * 一个像素占的字节

      比如一张512*512纹理,R5G6B5格式 = 512 * 512 *(一个像素占的字节) = 512*512*2/1024k= 0.5M

    如果你使用的是mipmap贴图,那么其大小将是普通图片的1.3倍左右。

    • 二、选择纹理压缩格式的衡量标准

    • 解析速度

    在纹理操作中,读取纹理数据是关键步骤,所以解码速度至关重要。

    • 随机读取数据

    能快速的随机读取任意像素

    • 压缩率和纹理质量

    既要保证一个不错的压缩效果,也要把纹理损失控制在一定范围内

    • 压缩速度

    通常纹理压缩在渲染前已经提前准备好,所以如果压缩的速度比解析速度慢,也是可以接受的。

    • 压缩格式

    使用目标平台支持的纹理压缩格式时,GPU可以直接使用它,没有增加消耗;

    如果目标平台不支持纹理压缩格式时,默认会将纹理解压成RGBA32或RGB32,然后与压缩的纹理一起存储在内存中,会增加纹理加载时间和增加额外内存。

    三、纹理压缩格式

    • png:

    无损压缩有透明,也是占体积最少的。都是基于整幅图片下进行的压缩,比如霍夫曼编码等,这样像素和像素之间在解码的过程中存在依赖关系,无法直接实现单个像素级别的解析,这就发挥不了显卡的并发能力,更重要的是问题在于无论是png还是jpg最终在显存中解码后都是RGBA的纹理格式,因此并无法减少显存的占用率。比如一张256*256的RGBA纹理,无论是png还是jpg格式,虽然文件大小不一样,在显卡中的大小仍然是256*256*4的显存空间

    • Jpg

    是有损压缩不透明。

    • DXT压缩原理:(PC端)

    是一种有损纹理压缩算法,可以说DXT是目前应用最广泛的纹理压缩格式,可以认为所有的PC端显卡都支持DXT压缩。在多数纹理压缩选择中都是最佳方案,几乎可以认为是PC下的标准压缩格式

    基本思想是把4x4的像素压缩成一个64或128位的数据块,是有损压缩方式。

    比如一个4*4像素R8G8B8格式的占的体积 = (4*4)(像素)*24(位)=384

    压缩后体积=2(像素,左上右下两个位置)*16(位) + 16(位置索引)*2(位) = 64

    DXT1中,4*4等于16个像素,然后将左上C0和右下C1保存两个颜色,其它颜色由这两个颜色进行差值计算,差值得到的另外两个颜色的公式为:C2=  2/3*C0 + 1/3*C1, C3 =  1/3*C0 + 2/3*C1。16位中R&B各占5位,但是G占了6位,这是因为人眼对绿色最为敏感。DXT1可以表示透明或不透明,通过左上大于右下表示完全不透明,反之表示透明。

    DXT1:4*4占用64位颜色

      DXT2/DXT3:4*4占用64位颜色加(64位表示透明信息也就是一个像素4位)=128位8个字,(0-3位表示透明,4-7表示颜色)主要用于Alpha通道较锐利,对比强烈的材质,比如镂空或部分半透材质等。

    DXT4/DXT5:4*4占用64位颜色加(64位表示透明信息(2个8位透明值+16个3位索引值))=128位8个字

      

    • ETC:(Android移动端)

     ETC1:不支持透明通道,所以仅能用于不透明纹理

     ETC1(不带Alpha)OpenGL2.0支持、ETC2(带Alpha)OpenGL3.0才支持

    压缩格式要求分辩率为2的次幂

    • PVR:(IOS)

    DXT的细节上缺陷明显,原因是当把纹理分成4*4区域后,块之间是独立的,虽然简化了压缩算法,但丢失了相邻间的相似性。而PVR则会考虑区域的右侧、下侧和右下侧区域的关联性。

    压缩格式要求压缩分辩率是正方形,分辩率为2的次幂

    PowerVR Texture Compression,PVRTC格式与基于块的压缩格式,比如S3TC、ETC的不同之处是,它使用2张双线性放大的低分辨率图,根据精度和每个像素的权重,融合到一起来呈现纹理,并且2-bpp和4-bpp都支持ARGB数据。PVRTC格式压缩比高,也是有损压缩。

    • 四、Unity纹理格式总结

    每位的像素点(bpp)是单个像素所需的存储量。该值越低,可以在GPU的缓存中存储的像素越多,从而可以更快地进行纹理访问。

    可变比特率(VBR)表示每个像素的比特不是固定值,而是取决于实际内容。VBR仅适用于Crunch压缩,并且仅适用于磁盘上的纹理大小。内存中的大小与使用基础纹理格式时的大小相同(例如,对于RGB Crunched DXT1,使用RGB Compressed DXT1)。

    Crunch compression是DXT或ETC Texture压缩之上的一种有损压缩格式(部分数据在压缩过程中丢失)。纹理在CPU上被解压缩为DXT或ETC,然后在运行时加载到GPU。

    Crunch compression有助于Texture使用尽可能少的磁盘空间,但对运行时内存使用没有影响。

    Crunch compression可能需要很长时间才能压缩,但是在运行时进行解压缩非常快。

    质量和压缩时间之间的平衡:质量越高,文件大小越大。为了获得最佳性能,尤其是在移动设备上,请使用应用程序所针对的硬件所支持的每像素位数最少的格式,只要该格式能够提供足够的视觉质量即可。

    使用目标平台支持的纹理压缩格式时,GPU可以直接使用它,没有增加消耗;

    如果目标平台不支持纹理压缩格式时,默认会将纹理解压成RGBA32或RGB32,然后与压缩的纹理一起存储在内存中,会增加纹理加载时间和增加额外内存。

     

    • 五、总结

    • Android采用RGBA Compressed ETC2 8 bits    不透明:RGB Compressed ETC 4 bits
    • iOS采用RGBA Compressed PVRTC 4 bits         不透明:RGB Compressed PVRTC 4 bits
    • 如果PVRTC不够清晰可选用ASTC格式,ASTC有更好的质量和灵活性,并且压缩速度比PVRTC快
    • PC采用RGBA Compressed DXT5                        不透明:RGBA Compressed DXT1
    • 渐变纹理采用RGBA32 
    • 要求清晰可采用:
    • (高清晰无压缩)采用RGBA32 
    • (中清晰中压缩)RGBA16+Dithering 要采用Floyd Steinberg抖动处理,不然渐变很明显,拉伸就会差距
    • (低清晰高压缩)ETC2 PVRTC
    • ASTC压缩率和清晰度都会比较好,支持的GPU :
      tvOS (all), iOS (A8以上,5S以下), Android (PowerVR 6XT, Mali T600 series, Adreno 400 series, Tegra K1)
      2016年之后的安卓手机基本支持这种压缩格式
      iphone6以及之后的机型支持这种压缩格式

    • 六、优化

    • 在Unity中根据不同平台,不同功能要求的清晰度来设置不同的压缩格式。

    参考:

    https://blog.csdn.net/wanglang3081/article/details/8869589

    https://blog.csdn.net/weixin_33814685/article/details/86431607?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1

    https://blog.csdn.net/ynnmnm/article/details/44983545

  • 相关阅读:
    JavaScript基础知识-流程控制之for循环
    JavaScript基础知识-流程控制之while循环
    HAProxy的高级配置选项-基于cookie实现的session保持实战案例
    HAProxy的四层与七层的区别及透传IP实战案例
    HAProxy基础配置-haproxy常见的调度算法
    HAProxy基础配置-配置haproxy的日志
    HAProxy基础配置-配置多进程多线程案例
    HAProxy基础配置-修改haproxy运行时的用户身份
    HAProxy基础配置-基于http的反向代理
    HAProxy基础配置-haproxy的配置文件说明
  • 原文地址:https://www.cnblogs.com/wwhhgg/p/12700208.html
Copyright © 2011-2022 走看看