NumStreamedMips
NumStreamedMips
#Overview
name: NumStreamedMips
This variable is created as a Console Variable (cvar).
- type:
Exec
- help:
Sorry: Exec commands have no help
It is referenced in 13
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of NumStreamedMips is to control the number of mip levels that can be streamed for textures in Unreal Engine 5. It is primarily used for texture streaming and LOD (Level of Detail) management within the rendering system.
NumStreamedMips is primarily used by the texture streaming subsystem, which is part of the Engine module. It’s specifically utilized in the FRenderAssetStreamingManager and FStreamingRenderAsset classes, which handle the streaming of render assets, including textures.
The value of this variable is typically set in the FTextureLODGroup structure, which is part of the texture LOD settings. It can be modified through the engine’s configuration system or via console commands.
NumStreamedMips interacts with other variables related to texture streaming and LOD management, such as MinAllowedMips, MaxAllowedMips, and ResourceState.MaxNumLODs. It’s used to calculate the minimum allowed mip level for a texture.
Developers should be aware that:
- A value of -1 for NumStreamedMips means all mips can be streamed.
- The variable is used per texture group, allowing for fine-grained control over different types of textures.
- Changing this value can significantly impact memory usage and streaming behavior.
Best practices when using this variable include:
- Carefully consider the balance between memory usage and visual quality when adjusting this value.
- Use different settings for different texture groups based on their importance and visibility in the game.
- Test thoroughly after making changes, as it can affect both performance and visual quality.
- Consider using the console command system for dynamic adjustments during development and debugging.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/TextureLODSettings.h:22
Scope (from outer to inner):
file
function FTextureLODGroup
Source code excerpt:
, LODBias_Smaller(-1)
, LODBias_Smallest(-1)
, NumStreamedMips(-1)
, MipGenSettings(TextureMipGenSettings::TMGS_SimpleAverage)
, MinLODSize(1)
, MaxLODSize(4096)
, MaxLODSize_Smaller(-1)
, MaxLODSize_Smallest(-1)
, MaxLODSize_VT(0)
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/TextureLODSettings.h:69
Scope: file
Source code excerpt:
/** Number of mip-levels that can be streamed. -1 means all mips can stream. */
UPROPERTY()
int32 NumStreamedMips;
/** Defines how the the mip-map generation works, e.g. sharpening */
UPROPERTY()
TEnumAsByte<TextureMipGenSettings> MipGenSettings;
/** Prevent LODBias from making the textures smaller than this value. Note that this does _not_ affect the smallest mip level size. */
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/StreamingManagerTexture.cpp:162
Scope (from outer to inner):
file
function FRenderAssetStreamingManager::FRenderAssetStreamingManager
Source code excerpt:
const TextureGroup TextureLODGroup = (TextureGroup)LODGroup;
const FTextureLODGroup& TexGroup = UDeviceProfileManager::Get().GetActiveProfile()->GetTextureLODSettings()->GetTextureLODGroup(TextureLODGroup);
NumStreamedMips_Texture[LODGroup] = TexGroup.NumStreamedMips;
// For compatibility reason, Character groups are always loaded with higher priority
Settings.HighPriorityLoad_Texture[LODGroup] = TexGroup.HighPriorityLoad || TextureLODGroup == TEXTUREGROUP_Character || TextureLODGroup == TEXTUREGROUP_CharacterSpecular || TextureLODGroup == TEXTUREGROUP_CharacterNormalMap;
}
// TODO: NumStreamedMips_StaticMesh, NumStreamedMips_SkeletalMesh, NumStreamedMips_LandscapeMeshMobile
NumStreamedMips_StaticMesh.Empty(1);
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/StreamingManagerTexture.cpp:540
Scope (from outer to inner):
file
function void FRenderAssetStreamingManager::ProcessAddedRenderAssets
Source code excerpt:
{
Asset->StreamingIndex = StreamingRenderAssets.Num();
const int32* NumStreamedMips = nullptr;
const int32 NumLODGroups = GetNumStreamedMipsArray(Asset->GetRenderAssetType(), NumStreamedMips);
new (StreamingRenderAssets) FStreamingRenderAsset(Asset, NumStreamedMips, NumLODGroups, Settings);
}
}
PendingStreamingRenderAssets.Reset();
}
void FRenderAssetStreamingManager::ConditionalUpdateStaticData()
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/StreamingManagerTexture.cpp:1242
Scope (from outer to inner):
file
function void FRenderAssetStreamingManager::UpdateIndividualRenderAsset
Source code excerpt:
if (!StreamingRenderAsset) return;
const int32* NumStreamedMips;
const int32 NumLODGroups = GetNumStreamedMipsArray(StreamingRenderAsset->RenderAssetType, NumStreamedMips);
StreamingRenderAsset->UpdateDynamicData(NumStreamedMips, NumLODGroups, Settings, false);
if (StreamingRenderAsset->bForceFullyLoad) // Somewhat expected at this point.
{
StreamingRenderAsset->WantedMips = StreamingRenderAsset->BudgetedMips = StreamingRenderAsset->MaxAllowedMips;
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/StreamingManagerTexture.cpp:1360
Scope (from outer to inner):
file
function void FRenderAssetStreamingManager::UpdateStreamingRenderAssets
lambda-function
Source code excerpt:
}
const int32* NumStreamedMips;
const int32 NumLODGroups = GetNumStreamedMipsArray(StreamingRenderAsset.RenderAssetType, NumStreamedMips);
StreamingRenderAsset.UpdateDynamicData(NumStreamedMips, NumLODGroups, Settings, bWaitForMipFading, &Packets[PacketIndex].LocalDeferredTickCBAssets); // We always use the Deferred CBs when doing the ParallelFor since those CBs are not thread safe.
// Make a list of each texture/mesh that can potentially require additional UpdateStreamingStatus
if (StreamingRenderAsset.RequestedMips != StreamingRenderAsset.ResidentMips)
{
Packets[PacketIndex].LocalInflightRenderAssets.Add(Index);
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/StreamingManagerTexture.cpp:1395
Scope (from outer to inner):
file
function void FRenderAssetStreamingManager::UpdateStreamingRenderAssets
Source code excerpt:
STAT(int32 PreviousResidentMips = StreamingRenderAsset.ResidentMips;)
const int32* NumStreamedMips;
const int32 NumLODGroups = GetNumStreamedMipsArray(StreamingRenderAsset.RenderAssetType, NumStreamedMips);
StreamingRenderAsset.UpdateDynamicData(NumStreamedMips, NumLODGroups, Settings, bWaitForMipFading, bAsync ? &DeferredTickCBAssets : nullptr);
// Make a list of each texture/mesh that can potentially require additional UpdateStreamingStatus
if (StreamingRenderAsset.RequestedMips != StreamingRenderAsset.ResidentMips)
{
InflightRenderAssets.Add(Index);
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/StreamingManagerTexture.cpp:2339
Scope (from outer to inner):
file
function bool FRenderAssetStreamingManager::HandleNumStreamedMipsCommand
Source code excerpt:
if ( NumMips >= -1 && NumMips <= MAX_TEXTURE_MIP_COUNT )
{
TexGroup.NumStreamedMips = NumMips;
}
Ar.Logf( TEXT("%s.NumStreamedMips = %d"), UTexture::GetTextureGroupString(TextureGroup(LODGroup)), TexGroup.NumStreamedMips );
}
else if (LODGroupType == TEXT("StaticMesh"))
{
// TODO
Ar.Logf(TEXT("NumStreamedMips command is not implemented for static mesh yet"));
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/StreamingManagerTexture.cpp:2929
Scope (from outer to inner):
file
function bool FRenderAssetStreamingManager::Exec
Source code excerpt:
return HandleShadowmapStreamingFactorCommand( Cmd, Ar );
}
else if (FParse::Command(&Cmd,TEXT("NumStreamedMips")))
{
return HandleNumStreamedMipsCommand( Cmd, Ar );
}
else if (FParse::Command(&Cmd,TEXT("TrackTexture"))
|| FParse::Command(&Cmd, TEXT("TrackRenderAsset")))
{
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/StreamingTexture.cpp:29
Scope (from outer to inner):
file
function FStreamingRenderAsset::FStreamingRenderAsset
Source code excerpt:
FStreamingRenderAsset::FStreamingRenderAsset(
UStreamableRenderAsset* InRenderAsset,
const int32* NumStreamedMips,
int32 NumLODGroups,
const FRenderAssetStreamingSettings& Settings)
: RenderAsset(InRenderAsset)
, RenderAssetType(InRenderAsset->GetRenderAssetType())
{
UpdateStaticData(Settings);
UpdateDynamicData(NumStreamedMips, NumLODGroups, Settings, false);
// In the editor, some paths can recreate the FStreamingRenderAsset, which could potentiallly trigger the unkown ref heuristic.
// To prevent this, we consider that the asset bindings where reset when creating the FStreamingRenderAsset.
// In game, we set it to FLT_MAX so that unkown ref heurisitic can kick in immeditaly (otherwise it incurs a 5 sec penalty on async loading)
InstanceRemovedTimestamp = GIsEditor ? FApp::GetCurrentTime() : -FLT_MAX;
DynamicBoostFactor = 1.f;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/StreamingTexture.cpp:167
Scope (from outer to inner):
file
function void FStreamingRenderAsset::UpdateDynamicData
Source code excerpt:
}
void FStreamingRenderAsset::UpdateDynamicData(const int32* NumStreamedMips, int32 NumLODGroups, const FRenderAssetStreamingSettings& Settings, bool bWaitForMipFading, TArray<UStreamableRenderAsset*>* DeferredTickCBAssets)
{
// Note that those values are read from the async task and must not be assigned temporary values!!
if (RenderAsset)
{
// Get the resource state after calling UpdateStreamingStatus() since it might have updated it.
const FStreamableRenderResourceState ResourceState = UpdateStreamingStatus(bWaitForMipFading, DeferredTickCBAssets);
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/StreamingTexture.cpp:236
Scope (from outer to inner):
file
function void FStreamingRenderAsset::UpdateDynamicData
Source code excerpt:
check(LODGroup < NumLODGroups);
if (NumStreamedMips[LODGroup] > 0)
{
MinAllowedMips = FMath::Clamp<int32>(ResourceState.MaxNumLODs - NumStreamedMips[LODGroup], ResourceState.NumNonStreamingLODs, MaxAllowedMips);
}
else
{
MinAllowedMips = ResourceState.NumNonStreamingLODs;
}
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/StreamingTexture.h:30
Scope: file
Source code excerpt:
FStreamingRenderAsset(
UStreamableRenderAsset* InRenderAsset,
const int32* NumStreamedMips,
int32 NumLODGroups,
const FRenderAssetStreamingSettings& Settings);
/** Update data that should not change unless changing settings. */
void UpdateStaticData(const FRenderAssetStreamingSettings& Settings);
/** Update data that the engine could change through gameplay. */
void UpdateDynamicData(const int32* NumStreamedMips, int32 NumLODGroups, const FRenderAssetStreamingSettings& Settings, bool bWaitForMipFading, TArray<UStreamableRenderAsset*>* DeferredTickCBAssets = nullptr);
/** Lightweight version of UpdateDynamicData. */
FStreamableRenderResourceState UpdateStreamingStatus(bool bWaitForMipFading, TArray<UStreamableRenderAsset*>* DeferredTickCBAssets = nullptr);
/**
* Returns the amount of memory used by the texture/mesh given a specified number of mip-maps, in bytes.