r.VirtualTextures
r.VirtualTextures
#Overview
name: r.VirtualTextures
The value of this variable can be defined or overridden in .ini config files. 1
.ini config file referencing this setting variable.
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
Is virtual texture streaming enabled?
It is referenced in 16
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of r.VirtualTextures is to enable or disable virtual texture streaming in Unreal Engine 5. Virtual texturing is a technique used to efficiently manage and stream large textures, particularly for rendering complex scenes with high-resolution textures.
This setting variable is primarily used in the rendering system and texture management subsystems of Unreal Engine. Based on the callsites, it is utilized in various modules and plugins, including:
- Engine core (Runtime/Engine)
- Texture Editor
- UnrealEd (Editor functionality)
- RenderCore
- Interchange system (for importing assets)
- Megascans Plugin
- Android and iOS Target Platforms
The value of this variable is typically set through the console or configuration files. It is defined as a console variable (CVarVirtualTextures) with a default value of 0 (disabled).
This variable interacts with several other variables and systems, such as:
- r.Mobile.VirtualTextures (for mobile platforms)
- r.VT.EnableAutoImport (for automatic importing of virtual textures)
- r.VT.MenuRestricted (for UI-related functionality)
- r.VT.AnisotropicFiltering (for texture filtering options)
Developers should be aware of the following when using this variable:
- Enabling virtual textures can significantly impact memory usage and rendering performance, especially on lower-end devices.
- It affects the import process of textures, potentially converting large textures to virtual textures automatically.
- It influences the behavior of texture conversion tools and editor functionality.
- The setting is platform-dependent and may have different effects on mobile platforms.
Best practices when using this variable include:
- Carefully consider the target platforms and their capabilities before enabling virtual textures.
- Test performance thoroughly with virtual textures enabled and disabled to ensure optimal results.
- Be aware of the automatic conversion of large textures to virtual textures during import, and adjust your workflow accordingly.
- Use in conjunction with other related virtual texturing settings for fine-tuned control over the system’s behavior.
- Consider the impact on build times and package sizes when using virtual textures extensively.
#Setting Variables
#References In INI files
Location: <Workspace>/Projects/Lyra/Config/DefaultEngine.ini:104, section: [/Script/Engine.RendererSettings]
- INI Section:
/Script/Engine.RendererSettings
- Raw value:
True
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Texture.cpp:55
Scope: file
Source code excerpt:
static TAutoConsoleVariable<int32> CVarVirtualTextures(
TEXT("r.VirtualTextures"),
0,
TEXT("Is virtual texture streaming enabled?"),
ECVF_RenderThreadSafe | ECVF_ReadOnly);
static TAutoConsoleVariable<int32> CVarMobileVirtualTextures(
TEXT("r.Mobile.VirtualTextures"),
#Loc: <Workspace>/Engine/Plugins/Bridge/Source/MegascansPlugin/Private/Utilities/MiscUtils.cpp:366
Scope (from outer to inner):
file
function bool AssetUtils::IsVTEnabled
Source code excerpt:
bool AssetUtils::IsVTEnabled()
{
static const auto CVarVirtualTexturesEnabled = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VirtualTextures"));
check(CVarVirtualTexturesEnabled);
static const auto CVarVirtualTexturesImportEnabled = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VT.EnableAutoImport"));
check(CVarVirtualTexturesEnabled);
const bool bVirtualTextureEnabled = CVarVirtualTexturesEnabled->GetValueOnAnyThread() != 0;
const bool bVirtualTextureImportEnabled = CVarVirtualTexturesImportEnabled->GetValueOnAnyThread() != 0;
#Loc: <Workspace>/Engine/Plugins/Editor/EngineAssetDefinitions/Source/Private/AssetDefinition_Texture.cpp:200
Scope (from outer to inner):
file
lambda-function
lambda-function
Source code excerpt:
if (const UContentBrowserAssetContextMenuContext* Context = UContentBrowserAssetContextMenuContext::FindContextWithAssets(InSection))
{
static const auto CVarVirtualTexturesEnabled = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VirtualTextures"));
check(CVarVirtualTexturesEnabled);
bool bVTEnabled = !! CVarVirtualTexturesEnabled->GetValueOnAnyThread();
static const auto CVarVirtualTexturesMenuRestricted = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VT.MenuRestricted"));
check(CVarVirtualTexturesMenuRestricted);
bool bVTMenuRestricted = !! CVarVirtualTexturesMenuRestricted->GetValueOnAnyThread();
if ( bVTEnabled && ! bVTMenuRestricted )
{
const bool bHasVirtualTextures =
Algo::AnyOf(Context->SelectedAssets, [](const FAssetData& AssetData){
bool VirtualTextured = false;
AssetData.GetTagValue<bool>("VirtualTextureStreaming", VirtualTextured);
return VirtualTextured;
});
const bool bHasNonVirtualTextures =
Algo::AnyOf(Context->SelectedAssets, [](const FAssetData& AssetData){
bool VirtualTextured = false;
AssetData.GetTagValue<bool>("VirtualTextureStreaming", VirtualTextured);
return !VirtualTextured;
});
if (bHasVirtualTextures)
{
const TAttribute<FText> Label = LOCTEXT("Texture_ConvertToRegular", "Convert VT to Regular Texture");
const TAttribute<FText> ToolTip = LOCTEXT("Texture_ConvertToRegularTooltip", "Converts this texture to a regular 2D texture if it is a virtual texture.");
const FSlateIcon Icon = FSlateIcon(FAppStyle::GetAppStyleSetName(), "ClassIcon.Texture2D");
const FToolMenuExecuteAction UIAction = FToolMenuExecuteAction::CreateStatic(&ExecuteConvertToRegularTexture);
InSection.AddMenuEntry("Texture_ConvertToRegular", Label, ToolTip, Icon, UIAction);
}
if (bHasNonVirtualTextures)
{
const TAttribute<FText> Label = LOCTEXT("Texture_ConvertToVT", "Convert to Virtual Texture");
const TAttribute<FText> ToolTip = LOCTEXT("Texture_ConvertToVTTooltip", "Converts this texture to a virtual texture if it exceeds the specified size.");
const FSlateIcon Icon = FSlateIcon(FAppStyle::GetAppStyleSetName(), "ClassIcon.Texture2D");
const FToolMenuExecuteAction UIAction = FToolMenuExecuteAction::CreateStatic(&ExecuteConvertToVirtualTexture);
InSection.AddMenuEntry("Texture_ConvertToVT", Label, ToolTip, Icon, UIAction);
}
}
}
}));
}
}));
});
}
#undef LOCTEXT_NAMESPACE
#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Import/Private/Texture/InterchangeTextureFactory.cpp:1449
Scope (from outer to inner):
file
namespace UE::Interchange::Private::InterchangeTextureFactory
function void SetupTexture2DSourceDataFromPayload
Source code excerpt:
// application of the existing settings above, so if a texture gets reimported at a larger size it will
// still be properly flagged as a VT (note: What about reimporting at a lower resolution?)
static const TConsoleVariableData<int32>* CVarVirtualTexturesEnabled = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VirtualTextures"));
check(CVarVirtualTexturesEnabled);
static const auto CVarVirtualTexturesAutoImportEnabled = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VT.EnableAutoImport"));
check(CVarVirtualTexturesAutoImportEnabled);
if (CVarVirtualTexturesEnabled->GetValueOnGameThread() && CVarVirtualTexturesAutoImportEnabled->GetValueOnGameThread())
#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Import/Private/Texture/InterchangeTexturePayloadData.cpp:50
Scope (from outer to inner):
file
function bool UE::Interchange::FImportImageHelper::IsImportResolutionValid
Source code excerpt:
if (Width > MaximumSupportedResolutionNonVT || Height > MaximumSupportedResolutionNonVT)
{
const TConsoleVariableData<int32>* CVarVirtualTexturesEnabled = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VirtualTextures")); check(CVarVirtualTexturesEnabled);
check(CVarVirtualTexturesEnabled != nullptr);
if (!CVarVirtualTexturesEnabled->GetValueOnAnyThread())
{
const FText VTMessage = NSLOCTEXT("Interchange", "Warning_LargeTextureVTDisabled", "\nWarning: Virtual Textures are disabled in this project.");
#Loc: <Workspace>/Engine/Source/Developer/Android/AndroidTargetPlatformSettings/Private/AndroidTargetPlatformSettings.cpp:71
Scope (from outer to inner):
file
function bool FAndroidTargetPlatformSettings::SupportsFeature
Source code excerpt:
case ETargetPlatformFeatures::VirtualTextureStreaming:
// TODO: should it check r.VirtualTextures for SM5 renderer ?
return bMobileVirtualTextures;
case ETargetPlatformFeatures::DistanceFieldAO:
return UsesDistanceFields();
#Loc: <Workspace>/Engine/Source/Developer/IOS/IOSTargetPlatform/Private/IOSTargetPlatform.cpp:491
Scope (from outer to inner):
file
function bool FIOSTargetPlatform::SupportsFeature
Source code excerpt:
case ETargetPlatformFeatures::VirtualTextureStreaming:
// TODO: should it check r.VirtualTextures for SM5 renderer?
return bMobileVirtualTextures;
case ETargetPlatformFeatures::DistanceFieldAO:
return UsesDistanceFields();
case ETargetPlatformFeatures::NormalmapLAEncodingMode:
#Loc: <Workspace>/Engine/Source/Editor/TextureEditor/Private/Customizations/TextureDetailsCustomization.cpp:130
Scope (from outer to inner):
file
function void FTextureDetails::CustomizeDetails
Source code excerpt:
if (VirtualTextureStreamingPropertyHandle.IsValid())
{
static const auto CVarVirtualTexturesEnabled = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VirtualTextures")); check(CVarVirtualTexturesEnabled);
const bool bVirtualTextureEnabled = CVarVirtualTexturesEnabled->GetValueOnAnyThread() != 0;
if (!bVirtualTextureEnabled)
{
DetailBuilder.HideProperty(VirtualTextureStreamingPropertyHandle);
}
}
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Factories/EditorFactories.cpp:4203
Scope (from outer to inner):
file
function UObject* UTextureFactory::FactoryCreateBinary
Source code excerpt:
}
static const auto CVarVirtualTexturesEnabled = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VirtualTextures"));
check(CVarVirtualTexturesEnabled);
// If the texture is larger than a certain threshold make it VT.
// Note that previously for re-imports we still checked size and potentially changed the VT status.
// But that was unintuitive for many users so now for re-imports we will end up ignoring this and respecting the existing setting below.
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Factories/EditorFactories.cpp:4524
Scope (from outer to inner):
file
function bool UTextureFactory::IsImportResolutionValid
Source code excerpt:
//UE::Interchange::FImportImageHelper::IsImportResolutionValid
static const auto CVarVirtualTexturesEnabled = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VirtualTextures")); check(CVarVirtualTexturesEnabled);
// Get the non-VT size limit :
int64 MaximumSupportedResolutionNonVT = (int64)UTexture::GetMaximumDimensionOfNonVT();
// limit on current rendering RHI : == GetMax2DTextureDimension()
const int64 CurrentRHIMaxResolution = int64(1)<<(GMaxTextureMipCount-1);
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Factories/EditorFactories.cpp:8211
Scope (from outer to inner):
file
function UTexture2D* UUDIMTextureFunctionLibrary::MakeUDIMVirtualTextureFromTexture2Ds
Source code excerpt:
UTexture2D* UUDIMTextureFunctionLibrary::MakeUDIMVirtualTextureFromTexture2Ds(FString OutputPathName, const TArray<UTexture2D*>& SourceTextures, const TArray<FIntPoint>& BlockCoords, bool bKeepExistingSettings, bool bCheckOutAndSave)
{
static const TConsoleVariableData<int32>* CVarVirtualTexturesEnabled = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VirtualTextures"));
check(CVarVirtualTexturesEnabled);
if (!CVarVirtualTexturesEnabled || !CVarVirtualTexturesEnabled->GetValueOnAnyThread())
{
UE_LOG(LogBlueprintUserMessages, Error, TEXT("Cannot create virtual textures when virtual texture support (r.VirtualTextures) is disabled."));
return nullptr;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Texture.cpp:639
Scope (from outer to inner):
file
function void UTexture::ValidateSettingsAfterImportOrEdit
Source code excerpt:
if ( bLargeTextureMustBeVT && ! VirtualTextureStreaming && MaxTextureSize == 0 )
{
static const auto CVarVirtualTexturesEnabled = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VirtualTextures"));
check( CVarVirtualTexturesEnabled != nullptr );
if ( CVarVirtualTexturesEnabled->GetValueOnAnyThread() )
{
if ( GetTextureClass() == ETextureClass::TwoD )
{
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Texture.cpp:3613
Scope (from outer to inner):
file
function void UTexture::GetBuiltTextureSize
Source code excerpt:
}
static const auto CVarVirtualTexturesEnabled = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VirtualTextures")); check(CVarVirtualTexturesEnabled);
const bool bVirtualTextureStreaming = CVarVirtualTexturesEnabled->GetValueOnAnyThread() && TargetPlatformSettings->SupportsFeature(ETargetPlatformFeatures::VirtualTextureStreaming) && VirtualTextureStreaming;
const UTextureLODSettings& LODSettings = TargetPlatformSettings->GetTextureLODSettings();
const uint32 LODBiasNoCinematics = FMath::Max<int32>(LODSettings.CalculateLODBias(SizeX, SizeY, MaxTextureSize, LODGroup, LODBias, 0, MipGenSettings, bVirtualTextureStreaming), 0);
SizeX = FMath::Max<int32>(SizeX >> LODBiasNoCinematics, 1);
SizeY = FMath::Max<int32>(SizeY >> LODBiasNoCinematics, 1);
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/TextureDerivedData.cpp:949
Scope (from outer to inner):
file
function static void GetTextureBuildSettings
Source code excerpt:
);
static const auto CVarVirtualTexturesEnabled = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VirtualTextures")); check(CVarVirtualTexturesEnabled);
// A ULightMapVirtualTexture2D with multiple layers saved in MapBuildData could be loaded with the r.VirtualTexture disabled, it will generate DDC before we decide to invalidate the light map data, to skip the ensure failure let it generate VT DDC anyway.
const bool bForVirtualTextureStreamingBuild = ULightMapVirtualTexture2D::StaticClass() == Texture.GetClass();
bool bVirtualTextureStreaming = bForVirtualTextureStreamingBuild || (CVarVirtualTexturesEnabled->GetValueOnAnyThread() && bPlatformSupportsVirtualTextureStreaming && Texture.VirtualTextureStreaming);
if (Texture.Availability == ETextureAvailability::CPU && TextureClass == ETextureClass::TwoD)
{
// We are swapping with a placeholder - don't VT it.
#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/RenderUtils.cpp:1126
Scope (from outer to inner):
file
function bool UseVirtualTexturing
Source code excerpt:
// does the project has it enabled ?
static const auto CVarVirtualTexture = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VirtualTextures"));
check(CVarVirtualTexture);
if (CVarVirtualTexture->GetValueOnAnyThread() == 0)
{
return false;
}
#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/Shader.cpp:2182
Scope (from outer to inner):
file
function void ShaderMapAppendKeyString
Source code excerpt:
const bool VTLightmaps = CVarVirtualTextureLightmaps && CVarVirtualTextureLightmaps->GetValueOnAnyThread() != 0;
static const auto CVarVirtualTexture = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VirtualTextures"));
bool VTTextures = CVarVirtualTexture && CVarVirtualTexture->GetValueOnAnyThread() != 0;
static const auto CVarVTAnisotropic = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.VT.AnisotropicFiltering"));
int32 VTFiltering = CVarVTAnisotropic && CVarVTAnisotropic->GetValueOnAnyThread() != 0 ? 1 : 0;
if (IsMobilePlatform(Platform) && VTTextures)