type
status
date
slug
summary
tags
category
icon
password
引子
UTextureLODSettings::CalculateLODBias(const UTexture* Texture, bool bIncCinematicMips) const
这个函数的作用是根据group设置的最大最小lodsize,以及当前贴图的最大尺寸,计算出两者差值,得到bias
代码
这个streaming最高的mip计算

我们看一下
CachedCombinedLODBias
的计算,平平无奇:关注
FStreamableRenderResourceState::AssetLODBias
的计算:

UTexture::GetResourcePostInitState
)AssetLODBias = AssetMipIdxForResourceFirstMip = GetCachedLODBias()-NumCinematicMipLevels
紧接着知道了实际上Streaming时的最大LOD数目,
MaxNumLODs=NumMips-AssetLODBias
,合情合理。接下来算运行streaming时允许的最大最小mip数目时,就考虑到了这个局部变量LODBias,即这节开头的引子

最终,Streaming时计算需要的mips时需要考虑
MaxAllowedNumMips
和MinAllowedNumMips
。

总结
总而言之,
FStreamingRenderAsset::MaxAllowedNumMips
以及FStreamingRenderAsset::MinAllowedNumMips
决定了可以StremIn/Out的贴图Mip范围。这两个值实际上受到了FStreamableRenderResourceState::MaxNumLODs
的直接影响,而这个MaxNumLODs
本身即是减去LODBias之后的值。在切画质(切换
ActiveDeviceProfile
)时并不会更新每个texture的CachedCombinedLODBias
,因此导致MaxNumLODs
以及MaxAllowedNumMips
实际上并不会有效更新,进而streaming的结果保持原有值。在切画质时,我组项目能看到贴图发生肉眼可见的原因,主要是独门秘技
InGameLODBias
在其中发挥作用,它会在计算MinAllowedNumMips
和MaxAllowedNumMips
时参与作用。目前该变量的设定是对战场景中贴图的最小LODBias(实际LODBias至少大于等于InGameLODBias
)。这意味着当
InGameLODBias
对所有画质为0时,贴图的画质只取决于它被创建时的画质,而不受后续画质切换改变,如果真是这个现状,我的评价是非常恐怖。得确认确认得再品品,看看哪里是不是能在切画质时搞点mip的计算数据更新,更新CachedLODBias,更新
FStreamableRenderResourceState
。一种可能的修复路径
这是目前我自己看下来觉得最安全的修复位置和修复方法,由于系统的复杂性,还是不踩屎坑了

- 作者:Dongfangliu
- 链接:https://www.morningheart.com/article/2ba761d8-2498-438f-9a4c-7a9b066329db
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。