yukamu 发表于 2023-1-12 14:49

URP自带的Tone mapping性能开销问题

1)URP自带的Tone mapping性能开销问题

2)图集中未使用到Sprite也会被加载到内存中的问题

3)GPU带宽:从纹理出发优化带宽①

4)GPU带宽:从纹理出发优化带宽②

5)GPU带宽:从纹理出发优化带宽③
<hr>
2023年伊始,从本期第320期的UWA《厚积薄发》开始,本专栏将以全新的面貌和大家见面。UWA将为大家精选UWA社区的热门话题,保留了经典的QA环节,并增加了UWA社区中相关的游戏开发技能,助力大家全面地掌握更多元的知识点。
Rendering

Q:想了解下URP自带的Tone mapping性能开销,有用过的大佬分享下吗?

A:Tone mapping,如果在LDR的情况下使用ACES的Tone mapping,会有非常高的开销,如果是HDR,则几乎是免费的,只有一个纹理采样的开销。因为HDR的情况下,会在LUT的DrawCall中将 Tone mapping烘焙到32x1024的小图里面,所以开销是非常低的。如果是LDR,ACES的Tone mapping则会在UberPost的DrawCall里面进行非常高分辨率(渲染分辨率)的计算,因此开销会非常高。另外一种Netural则不论HDR还是 LDR,只会令UberPost的复杂度增加2,但是LDR下的ACES则会让UberPost的复杂度增加23。

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

SpriteAtlas

Q:我有一个图集(里面包含两个图片:Sprite_A和Sprite_B),进入游戏后,调用spriteatlasBundle.LoadAssetWithSubAssetsAsync(“Sprite_A”);但是打开Profiler查看,发现Sprite_B也被加载到内存中了。这是正常的吗?

Unity版本:Unity 2020.3.26

A:这就是依赖加载。要检查出来,就是扫Prefab里面哪个依赖了这个资源。

Sprite本身的尺寸可以忽略。若图集加载了,图片就会有,Sprite那点消耗可以不关心。

值得注意的是,小心Sprite依赖加载,导致额外加载的整个图集。

感谢欧月松@UWA问答社区提供了回答

Rendering

GPU带宽:从纹理出发优化带宽①

如果大家看过很多实际项目的带宽数据,就不难总结出一个规律:一般读纹理带宽占带宽开销的大头。GPU在读纹理时会取当前画的像素附近N*N的区域到OnChip缓存中,若下一个像素要采样的点恰好落在这N*N中,就不需要向更远的地方去取造成更高的带宽,即通过这种方式降低了Cache Miss的概率。基于这个原理,我们对于绘制3D物体的贴图纹理要选择合适的分辨率,防止出现用大纹理画小物体时,画下一个像素时在大纹理上的采样点跳变,导致落在N*N范围内概率低的情况。最好的办法是直接为所有非2D UI的、有深度的物体的贴图纹理都开启Mipmap,此时GPU会自动选择合适的Mipmap分辨率层级,从而降低Cache Miss概率、有效控制带宽。

GPU带宽:从纹理出发优化带宽②

除了开Mipmap这个简单暴力的手段外,还需要关注:

开启各向异性或三线性插值会大幅增加采样次数,从而导致Cache Miss概率上升,移动端项目一般不建议用或项目中个别纹理效果使用即可。

另外,纹理格式也会造成影响,像RGBA32这种未压缩格式的纹理单个像素存储的信息越多,造成的带宽开销也就越高,应尽量使用压缩率更高的格式。

GPU带宽:从纹理出发优化带宽③

还有一种特殊的,也就是Render Texture资源需要额外提一下。其中,RT使用的精度越高,带宽开销越高,一般在移动端上用ARGB32格式或RGB111110Float就够了,如果用到ARGBHalf可能就存在浪费了;另外,RT的Copy、下采样操作也会造成较高的带宽,常见的如Copy Color、Copy Depth和Bloom后效都会产生较高带宽。

期待更多讨论,欢迎大家转至UWA社区交流


封面图来源于网络
<hr>
今天的分享就到这里。生有涯而知无涯,在漫漫的开发周期中,我们遇到的问题只是冰山一角,UWA社区愿伴你同行,一起探索分享。欢迎更多的开发者加入UWA社区。
页: [1]
查看完整版本: URP自带的Tone mapping性能开销问题