找回密码
 立即注册
查看: 284|回复: 0

UE内存优化

[复制链接]
发表于 2024-7-15 18:15 | 显示全部楼层 |阅读模式
本文介绍Unreal中纹理的几种优化方式,以及Profile方式。
纹理体积对游戏性能的影响主要表此刻内存,显存和打包后的体积容量,不会影响衬着性能。内存和带宽瓶颈会造成的问题是:延迟,卡顿,而不是帧数整体偏低。
主要介绍的三种方式为:纹理压缩,TextureStreaming,DownScale和MaxSize。
纹理压缩

压缩要求:纹理的长和宽都要是4的倍数
纹理压缩是这三种中对Texture内存占用最有效的方式,一般可以将占用可以缩小到3到6倍。
建议所有纹理都使用压缩措置。



Figure 1. 未压缩的Texture概略21Mb



Figure 2. DXT5压缩格式压缩后,5.4Mb

纹理压缩在分歧的平台是有区此外,在PC平台上主要是基于块式的压缩方案BC(Block Compression),也叫DXTC(DirectX Texture Compression)。因为都是以4 * 4像素块为一个压缩单元,因此纹理的尺寸要求是4的倍数。
即使是BC/DXTC类别中也有大量分歧的压缩格式,BC1/2/3/4/5/6/7。主要是按照是否有Alpha通道,是否撑持法线贴图,以及减少压缩导致的信息损掉决定。
BC1:RGB通道纹理压缩

适用范围:无Alpha通道
效果:将(4*4)16个RGB8格式的纹素,最终压缩成只有4种颜色的块。可以仔细不雅察看下图右侧压缩后的纹素块,实际只有4种颜色。



Figure 3. BC1压缩图解

道理:

  • (4*4 )16个纹素记录两个极值颜色(RGB565),即Color_0和Color_1

    • 这两个极值,再线性插值出两个数值Color_2, Color_3。

  1. Color_2 = 1/3 * Color_0 + 2/3 * Color_1;
  2. Color_3 = 2/3 * Color_0 + 1/3 * Color_1;
复制代码


    • 至此,16个纹素的颜色就只用4个颜色代替

  • 16个纹素,每个纹素记录2bit索引

    • 2bit可以组成4种选择(00/01/10/11)对应此中一种颜色

至此,16个RGB8的纹素,从16 * 24 = 384bit(图中因为有A通道所以是512,但压缩后A通道会消掉)。压缩到(R5G6B5 * 2) + (4 * 4 * 2) = 64bit。
每纹素压缩率6 : 1,4bpp (bit per pixel)
BC2/3:RGBA纹理压缩

BC2/3都可以用来压缩带Alpha通道的纹理,压缩后都是128bit的块。A通道也都是占用了64bit,只是对A通道的压缩方式不太不异。由此可见,A通道的数据量占整体压缩后的一半,Texture中能不使用A通道,就不使用A通道
PS:
(可以通过MergeMaps将三张Alpha单通道Texture,合并到一张RGB Texture的方式节省Alpha的内存占用。)
(同时减少了shader的纹理采样数目,限制是16个)
BC2:

  • BC2在RGB的措置上和BC1不异
  • BC2对A通道的措置:

    • 每个纹素的A通道,用一个4bit的Alpha替换原本的Alpha值
    • 相当于最大还可以是16种Alpha值,只是精度下降

  • 每纹素压缩率4 : 1,8bpp (bit per pixel)



Figure 4. BC2压缩图解

BC3:

  • BC3在RGB的措置上和BC1不异
  • BC3对A通道的措置:

    • 16个纹素记录两个Alpha 8bit的极值,即Alpha_0和Alpha_1
    • 通过两个极值,在插出6个值,一共8个值。
    • 每个纹素用3bit纪录一个索引,一共8种索引

  • 每纹素压缩率4 : 1,8bpp (bit per pixel)



Figure 5. BC3压缩图解

BC4:用于单通道

BC4压缩道理:

  • 单个通道,压缩方式和BC3中的Alpha不异。
  • 每纹素压缩率2 : 1,4bpp (bit per pixel)
  • 适合Alpha 通道



Figure 6. BC4压缩道理

BC5/DXT5:用于法线贴图

BC5只有两个通道,是用于法线贴图的一种压缩格式。Normal Map是一种很出格的纹理,Unreal衬着过程中的Normal Map实际上是没有Blue通道的,B通道可以通过RG通道颠末计算还原。还原算法
  1. Z = sqrt(1 - (x * x + y * y));
复制代码


Figure 7. UE中使用DeriverNormalZ通过RG还原B通道

只是在编纂器中依然可以看到Blue。下图展示RendeDoc截帧成果。



Figure 8. RenderDoc中可以看到法线贴图只有RG两个通道

BC5压缩道理:

  • 两个通道,每个通道压缩方式和BC3中的Alpha不异。两个8位参考RG值 + 每个纹素3位RG插值因子 = 共128位.
  • 每纹素压缩率2 : 1,8bpp (bit per pixel)
  • 适合Normal Map



Figure 9. BC5压缩图解

BC6H:用于HDR纹理的压缩

BC6H解决了BC1可选颜色太少,且精度低的问题。可以用来压缩HDR纹理,但是BC6H没有Alpha通道。压缩后的4*4纹素块,占128bit的体积。



Figure 10. UE中HDR压缩格式为BC6H

TextureStreaming

TextureStreaming对纹理的要求:

  • 纹理的长宽都是2的幂,且生成Mipmap
  • 纹理不要勾选Never Streaming
MipMap

Mipmap的感化:措置因纹理本身过于精细,但是占屏幕面积小对应屏幕上的分辩率不足(也就是采样率不足)导致的锯齿。
这个问题也可以使用MSAA解决,MSAA通过在一个像素中多次采样提高采样率,但是计算量过大。而Mipmap通过每级长宽缩小一半的小贴图,实现将原本大纹理信息合并到小纹理中。这个过程的道理和MSAA/SSAA不异。因此Mipmap通过增加1/3的整体纹理体积,提供更好的效果。



Figure 11. MipMap道理

效果对比:



Figure 12. 左侧使用Mipmap,右侧未使用Mipmap

如何确定MipMap的层级

按照相邻两个像素之间的UV距离决定。
当像素和上下两个像素之间的UV距离(ddx, ddy)刚好或接近是一个纹素值,如下图蓝色的点。说明一个像素基本可以代表一个纹素,长宽为“2的0幂”的纹素块,那就使用Mip0,即原图。
当像素和上下两个像素之间的UV距离达到或接近L个纹素值,如下图红色的点基本是3个纹素值。说明一个像素覆盖了多个纹素,可以近似为长宽为“2的x幂”的纹素块。也就是MipMap_x,计算x的公式如下
将L = 3代入公式,可以得到x为2。即一个像素概略覆盖长宽为“2的2幂”的纹素块。使用MipMap2。
  1. int x = max(int(log2(L) + 0.5),0)
复制代码


Figure 13. 确定MipMap Level

如何确定两个像素之间的纹素距离L:
L = max(\sqrt{\left( \frac{du}{dx} \right)^{2} + \left( \frac{dv}{dx} \right)^{2}}, \sqrt{\left( \frac{du}{dy} \right)^{2} + \left( \frac{dv}{dy} \right)^{2}})
  1. float2 dx = ddx(uv);
  2. float2 dy = ddy(uv);
  3. float L = max(sqrt(dot(dx, dx)), sqrt(dot(dy, dy));
复制代码
Texture Streaming道理

只加载该纹理需要被用到的阿谁Mip Level,不用加载全部Mipmap。用这种法子在拥有良好的视觉质量, 同时有效地打点可用内存。
Streaming 指标

UE中提供了STAT命令还显示TextureStreaming的指标 - “stat Streaming”



Figure 14. Stat streaming示例

官方提供了斗劲详细的指标解释和命令。
斗劲重要的几点:

  • Texture Pool约等于Safety Pool+Temporary Pool+Streaming Pool+NonStreaming Mips
  • Streaming Pool的需要容量是Visible Mips+Hidden Mips+Forced Mips+Cached Mips,但可以更大
  • Wanted Mips等于Visible Mips+Hidden Mips+Forced Mips
  • Streaming Pool的大小可以通过r.Streaming.PoolSize控制

    • 如果调的很小,在Editor中会看到左上角警告,以及场景中纹理变得非常模糊
    • Streaming Pool足够大时,Required Pool等于Wanted Mips
    • Streaming Pool稍小于Required Pool,Cached Mips就会逐渐从内存里释放
    • Streaming Pool远小于Required Pool,引擎会只加载最小的Mipmap。因此场景中纹理变得非常模糊,打出的包可能会直接闪退


使用建议:


  • UI可以不使用,因为本身就在最上层用不到Mip0外的level,打开Mipmap还增加了1/3的内存占用。
  • 本身就很小的纹理可以不使用。
  • 其他纹理都应该使用Texture Streaming。
DownScale和MaxSize

DownScale可以设置在分歧平台长宽各缩短几倍,此时要注意DownScale后的纹理大小也要满足压缩要求。否则还会导致包体体积上升。设置为2后,移动端该纹理会使用1024*1024的分辩率。



Figure 15. DownScale图解

Maximum Texture Size用来设置该Texture在游戏中最大以什么分辩率显示,属于斗劲强硬的改削方式。建议改削前和美术沟通。默认数值为0,即不生效。



Figure 16. Maximum Texture Size图解

Tracking the Size of texture

LLM
Memreport -full
参考


  • http://sv-journal.org/2014-1/06/en/index.php?lang=en
  • About Texture Compression Techniques
  • Kyrie:纹理压缩
  • UE4:关于Texture Streaming的一部门总结 - 知乎 (zhihu.com)
  • 虚幻引擎纹理流送指标 | 虚幻引擎5.1文档 (unrealengine.com)
  • 虚幻引擎中的纹理流送配置 | 虚幻引擎5.1文档 (unrealengine.com)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-23 17:28 , Processed in 0.161611 second(s), 28 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表