TextureLODGroups

TextureLODGroups

#Overview

name: TextureLODGroups

The value of this variable can be defined or overridden in .ini config files. 42 .ini config files referencing this setting variable.

It is referenced in 26 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of TextureLODGroups is to manage texture Level of Detail (LOD) settings for different texture groups in Unreal Engine 5. This variable is used to control various aspects of texture rendering and loading, such as mip-map generation, filtering, and streaming.

TextureLODGroups is primarily used by the rendering system and texture streaming subsystem in Unreal Engine. It’s part of the UTextureLODSettings class, which is utilized by the UDeviceProfile class to define texture LOD behavior for different device profiles.

The value of this variable is typically set in the device profile configuration. It can be modified through the Unreal Editor’s project settings or programmatically at runtime.

TextureLODGroups interacts with several other variables and systems, including:

  1. LODGroup property of UTexture objects
  2. MipGenSettings for controlling mip-map generation
  3. Texture streaming system for managing texture loading and unloading

Developers should be aware of the following when using this variable:

  1. Changes to TextureLODGroups can significantly impact game performance and visual quality.
  2. Different platforms or devices may require different LOD settings for optimal performance.
  3. Modifying these settings at runtime may have performance implications.

Best practices when using TextureLODGroups include:

  1. Carefully consider the balance between visual quality and performance when adjusting LOD settings.
  2. Use appropriate LOD groups for different types of textures (e.g., world textures, character textures, UI textures).
  3. Test LOD settings on target devices to ensure optimal performance and visual quality.
  4. Be cautious when modifying these settings at runtime, as it may impact performance or cause visual artifacts.
  5. Utilize the device profile system to tailor LOD settings for different hardware configurations.

#Setting Variables

#References In INI files

<Workspace>/Engine/Config/BaseDeviceProfiles.ini:4, section: [DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:148, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:149, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:150, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:151, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:152, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:153, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:154, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:155, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:156, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:157, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:158, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:159, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:160, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:161, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:162, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:163, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:164, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:165, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:166, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:167, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:168, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:169, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:170, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:171, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:172, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:173, section: [GlobalDefaults DeviceProfile]
<Workspace>/Engine/Config/BaseDeviceProfiles.ini:174, section: [GlobalDefaults DeviceProfile]
<Workspace>/Projects/Lyra/Config/DefaultDeviceProfiles.ini:12, section: [GlobalDefaults DeviceProfile]
<Workspace>/Projects/Lyra/Config/DefaultDeviceProfiles.ini:20, section: [Mobile DeviceProfile]
<Workspace>/Projects/Lyra/Config/DefaultDeviceProfiles.ini:21, section: [Mobile DeviceProfile]


... omitting 12 locations ...

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Plugins/Developer/TextureFormatOodle/Source/Private/TextureFormatOodle.cpp:130

Scope: file

Source code excerpt:


[GlobalDefaults DeviceProfile]
@TextureLODGroups=Group
TextureLODGroups=(Group=TEXTUREGROUP_World,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage,LossyCompressionAmount=TLCA_High)
+TextureLODGroups=(Group=TEXTUREGROUP_WorldNormalMap,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage,LossyCompressionAmount=TLCA_Low)
+TextureLODGroups=(Group=TEXTUREGROUP_WorldSpecular,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)


If the LossyCompressionAmount is not set on the LODGroup (which is the default), 
then it falls through to the global default, which is set in the texture compression
project settings.

At each stage, TLCA_Default means "inherit from parent".

TLCA_None means disable RDO entirely. We do not recommend this, use TLCA_Lowest 
instead when you need very high quality.

Note that the Unreal Editor texture dialog shows live compression results.
When you're in the editor and you adjust the LossyCompressionAmount or import a 
new texture, it shows the Oodle Texture encoded result in the texture preview.



*********/


DEFINE_LOG_CATEGORY_STATIC(LogTextureFormatOodle, Log, All);
LLM_DEFINE_TAG(OodleTexture);

/*****************
* 
* Function pointer types for the Oodle Texture functions we need to import :
* 
********************/

OODEFFUNC typedef OodleTex_Err (OOEXPLINK t_fp_OodleTex_EncodeBCN_RDO_Ex)(
    OodleTex_BC to_bcn,void * to_bcn_blocks,OO_SINTa num_blocks,
    const OodleTex_Surface * from_surfaces,OO_SINTa num_from_surfaces,OodleTex_PixelFormat from_format,
    const OodleTex_Layout * layout,
    int rdo_lagrange_lambda,
    const OodleTex_RDO_Options * options,
    int num_job_threads,void * jobify_user_ptr);
	
OODEFFUNC typedef void (OOEXPLINK t_fp_OodleTex_Plugins_SetAllocators)(
    t_fp_OodleTex_Plugin_MallocAligned * fp_OodleMallocAligned,
    t_fp_OodleTex_Plugin_Free * fp_OodleFree);
	
OODEFFUNC typedef void (OOEXPLINK t_fp_OodleTex_Plugins_SetJobSystemAndCount)(
    t_fp_OodleTex_Plugin_RunJob * fp_RunJob,
    t_fp_OodleTex_Plugin_WaitJob * fp_WaitJob,
    int target_parallelism);
	
OODEFFUNC typedef t_fp_OodleTex_Plugin_Printf * (OOEXPLINK t_fp_OodleTex_Plugins_SetPrintf)(t_fp_OodleTex_Plugin_Printf * fp_rrRawPrintf);

OODEFFUNC typedef t_fp_OodleTex_Plugin_DisplayAssertion * (OOEXPLINK t_fp_OodleTex_Plugins_SetAssertion)(t_fp_OodleTex_Plugin_DisplayAssertion * fp_rrDisplayAssertion);

OODEFFUNC typedef const char * (OOEXPLINK t_fp_OodleTex_Err_GetName)(OodleTex_Err error);

OODEFFUNC typedef const char * (OOEXPLINK t_fp_OodleTex_PixelFormat_GetName)(OodleTex_PixelFormat pf);

OODEFFUNC typedef const char * (OOEXPLINK t_fp_OodleTex_BC_GetName)(OodleTex_BC bcn);

OODEFFUNC typedef const char * (OOEXPLINK t_fp_OodleTex_RDO_UniversalTiling_GetName)(OodleTex_RDO_UniversalTiling tiling);

OODEFFUNC typedef OO_S32 (OOEXPLINK t_fp_OodleTex_BC_BytesPerBlock)(OodleTex_BC bcn);

OODEFFUNC typedef OO_S32 (OOEXPLINK t_fp_OodleTex_PixelFormat_BytesPerPixel)(OodleTex_PixelFormat pf);

OODEFFUNC typedef OodleTex_Err (OOEXPLINK t_fp_OodleTex_LogVersion)(void);

/**
 * DebugInfo passed to the Jobify callbacks for tracing 
 */
struct FOodleJobDebugInfo
{
	FStringView DebugTexturePathName;
	int32 SizeX;
	int32 SizeY;
	OodleTex_BC OodleBCN;
	int RDOLambda;
};


struct FOodleTextureVTable;

static void TFO_Plugins_Init();
static void TFO_Plugins_Install(const FOodleTextureVTable * VTable);

/**
* 
* FOodleTextureVTable provides function calls to a specific version of the Oodle Texture dynamic lib
*   multiple FOodleTextureVTables may be loaded to support multi-version encoding
* 
**/
struct FOodleTextureVTable
{
	const TCHAR * VersionString = nullptr;
	FName	Version;

	// LoadedDynamicLib is set on first use
	//	if either of LoadedDynamicLib or LoadFailed is set, a load was attempted, don't try again
	//	if both == 0, load has not been tried yet
	void * LoadedDynamicLib  = nullptr;
	std::atomic<int> LoadResult = 0; // 0 = not done, 1 = ok, -1 = fail
	FCriticalSection DynamicLibLoadLock;

	t_fp_OodleTex_EncodeBCN_RDO_Ex * fp_OodleTex_EncodeBCN_RDO_Ex = nullptr;

	t_fp_OodleTex_Plugins_SetAllocators * fp_OodleTex_Plugins_SetAllocators = nullptr;
	t_fp_OodleTex_Plugins_SetJobSystemAndCount * fp_OodleTex_Plugins_SetJobSystemAndCount = nullptr;
	t_fp_OodleTex_Plugins_SetPrintf * fp_OodleTex_Plugins_SetPrintf = nullptr;
	t_fp_OodleTex_Plugins_SetAssertion * fp_OodleTex_Plugins_SetAssertion = nullptr;
	
	t_fp_OodleTex_Err_GetName * fp_OodleTex_Err_GetName = nullptr;
	t_fp_OodleTex_PixelFormat_GetName * fp_OodleTex_PixelFormat_GetName = nullptr;
	t_fp_OodleTex_BC_GetName * fp_OodleTex_BC_GetName = nullptr;
	t_fp_OodleTex_RDO_UniversalTiling_GetName * fp_OodleTex_RDO_UniversalTiling_GetName = nullptr;
	t_fp_OodleTex_BC_BytesPerBlock * fp_OodleTex_BC_BytesPerBlock = nullptr;
	t_fp_OodleTex_PixelFormat_BytesPerPixel * fp_OodleTex_PixelFormat_BytesPerPixel = nullptr;

	FOodleTextureVTable()
	{
	}

	void Init(const TCHAR * InVersionString)
	{
		// this runs from Module init, threads are not running
		VersionString = InVersionString;
		Version = FName(InVersionString);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/DeviceProfiles/DeviceProfile.h:49

Scope (from outer to inner):

file
class        class UDeviceProfile : public UTextureLODSettings

Source code excerpt:

public:

	/* Need to add missing entries in TextureLODGroups to match enum TextureGroup when the device profile is reloaded*/
	virtual void PostReloadConfig(class FProperty* PropertyThatWasLoaded) override
	{
		Super::PostReloadConfig(PropertyThatWasLoaded);

		ValidateTextureLODGroups();
	}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/DeviceProfiles/DeviceProfile.h:106

Scope (from outer to inner):

file
class        class UDeviceProfile : public UTextureLODSettings

Source code excerpt:

	
private:
	// Make sure our TextureLODGroups array is sorted correctly and complete
	ENGINE_API void ValidateTextureLODGroups();
	/** Delegate object fired when there has been any changes to the console variables */
	FOnCVarsUpdated CVarsUpdatedDelegate;

public:
	// The selected result after running the MatchingRules process.

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/TextureLODSettings.h:232

Scope (from outer to inner):

file
class        class UTextureLODSettings : public UObject

Source code excerpt:


	/**
	 * TextureLODGroups access with bounds check
	 *
	 * @param   GroupIndex      usually from Texture.LODGroup
	 * @return                  A handle to the indexed LOD group. 
	 */
	ENGINE_API FTextureLODGroup& GetTextureLODGroup(TextureGroup GroupIndex);

	/**
	* TextureLODGroups access with bounds check
	*
	* @param   GroupIndex      usually from Texture.LODGroup
	* @return                  A handle to the indexed LOD group.
	*/
	ENGINE_API const FTextureLODGroup& GetTextureLODGroup(TextureGroup GroupIndex) const;

protected:
	ENGINE_API void SetupLODGroup(int32 GroupId);

public:

	/** Array of LOD settings with entries per group. */
	UPROPERTY(EditAnywhere, config, Category="Texture LOD Settings")
	TArray<FTextureLODGroup> TextureLODGroups;
};

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfile.cpp:114

Scope (from outer to inner):

file
function     void UDeviceProfile::ValidateTextureLODGroups

Source code excerpt:

{
	// Ensure the Texture LOD Groups are in order of TextureGroup Enum
	TextureLODGroups.Sort([]
		(const FTextureLODGroup& Lhs, const FTextureLODGroup& Rhs)
		{
			return (int32)Lhs.Group < (int32)Rhs.Group;
		}
	);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfile.cpp:126

Scope (from outer to inner):

file
function     void UDeviceProfile::ValidateTextureLODGroups

Source code excerpt:

	for (int32 GroupId = 0; GroupId < (int32)TEXTUREGROUP_MAX; ++GroupId)
	{
		if (TextureLODGroups.Num() < (GroupId + 1) || TextureLODGroups[GroupId].Group > GroupId)
		{
			if (ParentProfile && (ParentProfile->TextureLODGroups.Num() > GroupId))
			{
				TextureLODGroups.Insert(ParentProfile->TextureLODGroups[GroupId], GroupId);
			}
			else
			{
				TextureLODGroups.Insert(FTextureLODGroup(), GroupId);
			}

			TextureLODGroups[GroupId].Group = (TextureGroup)GroupId;
		}
	}

#define SETUPLODGROUP(GroupId) SetupLODGroup(GroupId);
	FOREACH_ENUM_TEXTUREGROUP(SETUPLODGROUP)
#undef SETUPLODGROUP

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfileManager.cpp:1009

Scope (from outer to inner):

file
function     void UDeviceProfileManager::SaveProfiles

Source code excerpt:

					// Strip out runtime inherited texture groups before save
					UDeviceProfile* ParentProfile = CurrentProfile->GetParentProfile(true);
					if (ParentProfile && CurrentProfile->TextureLODGroups.Num() == ParentProfile->TextureLODGroups.Num())
					{
						// Remove any that are the same, these are saved as a keyed array so the rest will inherit
						for (int32 i = CurrentProfile->TextureLODGroups.Num() - 1; i >= 0; i--)
						{
							if (CurrentProfile->TextureLODGroups[i] == ParentProfile->TextureLODGroups[i])
							{
								CurrentProfile->TextureLODGroups.RemoveAt(i);
							}
						}
					}
					
					CurrentProfile->TryUpdateDefaultConfigFile();

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfileManager.cpp:1192

Scope (from outer to inner):

file
function     bool UDeviceProfileManager::AreTextureGroupsTheSame

Source code excerpt:


	// If our groups are identical say yes
	if (Profile1->TextureLODGroups == Profile2->TextureLODGroups)
	{
		return true;
	}

	UDeviceProfile* Parent1 = Profile1->GetParentProfile(true);
	UDeviceProfile* Parent2 = Profile2->GetParentProfile(true);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfileManager.cpp:1202

Scope (from outer to inner):

file
function     bool UDeviceProfileManager::AreTextureGroupsTheSame

Source code excerpt:

	// Also if both profiles inherit groups with no changes, count them as the same
	if (Parent1 && Parent2 &&
		Profile1->TextureLODGroups == Parent1->TextureLODGroups &&
		Profile2->TextureLODGroups == Parent2->TextureLODGroups)
	{
		return true;
	}

	return false;
}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfileManager.cpp:1329

Scope (from outer to inner):

file
function     void UDeviceProfileManager::SetActiveDeviceProfile

Source code excerpt:

	{
		UDeviceProfile* Profile = Cast<UDeviceProfile>(Profiles[Idx]);
		const void* TextureLODGroupsAddr = Profile ? Profile->TextureLODGroups.GetData() : nullptr;
		const int32 NumTextureLODGroups = Profile ? Profile->TextureLODGroups.Num() : 0;
		UE_LOG(LogDeviceProfileManager, Verbose, TEXT("\t[%p][%p %d] %s, "), Profile, TextureLODGroupsAddr, NumTextureLODGroups, Profile ? *Profile->GetName() : TEXT("None"));
	}

	const void* TextureLODGroupsAddr = ActiveDeviceProfile ? ActiveDeviceProfile->TextureLODGroups.GetData() : nullptr;
	const int32 NumTextureLODGroups = ActiveDeviceProfile ? ActiveDeviceProfile->TextureLODGroups.Num() : 0;
	UE_LOG(LogDeviceProfileManager, Log, TEXT("Active device profile: [%p][%p %d] %s"), ActiveDeviceProfile, TextureLODGroupsAddr, NumTextureLODGroups, ActiveDeviceProfile ? *ActiveDeviceProfile->GetName() : TEXT("None"));

#if CSV_PROFILER
	CSV_METADATA(TEXT("DeviceProfile"), *GetActiveDeviceProfileName());
#endif

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DeviceProfiles/DeviceProfileManager.cpp:1457

Scope (from outer to inner):

file
class        class FPlatformCVarExec : public FSelfRegisteringExec
function     virtual bool Exec_Runtime

Source code excerpt:


				// log out the LODGroups fully
				FArrayProperty* LODGroupsProperty = FindFProperty<FArrayProperty>(UDeviceProfile::StaticClass(), GET_MEMBER_NAME_CHECKED(UTextureLODSettings, TextureLODGroups));
				FScriptArrayHelper_InContainer ArrayHelper(LODGroupsProperty, DeviceProfile);
				for (int32 Index = 0; Index < ArrayHelper.Num(); Index++)
				{
					FString	Buffer;
					LODGroupsProperty->Inner->ExportTextItem_Direct(Buffer, ArrayHelper.GetRawPtr(Index), ArrayHelper.GetRawPtr(Index), DeviceProfile, 0);
					Ar.Logf(TEXT("LODGroup[%d]=%s"), Index, *Buffer);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Streaming/StreamingManagerTexture.cpp:2787

Scope (from outer to inner):

file
function     bool FRenderAssetStreamingManager::HandleInvestigateRenderAssetCommand

Source code excerpt:


						// LOD group Bias : see UTextureLODSettings::CalculateLODBias(), included in CachedCombinedLODBias
						const FTextureLODGroup& LODGroupInfo = UDeviceProfileManager::Get().GetActiveProfile()->GetTextureLODSettings()->TextureLODGroups[StreamingRenderAsset.LODGroup];
						if (LODGroupInfo.LODBias)
						{
							if (FPlatformProperties::RequiresCookedData())
							{
								BiasDesc += FString::Printf(TEXT(" [LODGroup.Bias:0(%d)]"), LODGroupInfo.LODBias);
							}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Texture.cpp:1526

Scope (from outer to inner):

file
function     bool UTexture::IsCookPlatformTilingDisabled

Source code excerpt:

		check(TextureLODSettings);

		checkf(LODGroup < TextureLODSettings->TextureLODGroups.Num(), 
			TEXT("A texture had passed a bad LODGroup to UTexture::IsCookPlatformTilingDisabled (%d, out of %d groups). The texture name is '%s'."), 
			LODGroup, TextureLODSettings->TextureLODGroups.Num(), *GetPathName());

		return TextureLODSettings->TextureLODGroups[LODGroup].CookPlatformTilingDisabled;
	}

	return CookPlatformTilingSettings.GetValue() == TextureCookPlatformTilingSettings::TCPTS_DoNotTile;
}

void UTexture::SetDeterministicLightingGuid()

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/TextureDerivedData.cpp:2599

Scope (from outer to inner):

file
function     static void SerializePlatformData

Source code excerpt:


				OptionalMips = Ar.CookingTarget()->GetTextureLODSettings().CalculateNumOptionalMips(LODGroup, FirstMipWidth, FirstMipHeight, NumMips, FirstInlineMip, Texture->MipGenSettings);
				bDuplicateNonOptionalMips = Ar.CookingTarget()->GetTextureLODSettings().TextureLODGroups[LODGroup].DuplicateNonOptionalMips;

				// OptionalMips must be streaming mips.
				check(OptionalMips <= FirstInlineMip);
			}

		#endif

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/TextureLODSettings.cpp:129

Scope (from outer to inner):

file
function     void UTextureLODSettings::SetupLODGroup

Source code excerpt:

void UTextureLODSettings::SetupLODGroup(int32 GroupId)
{
	TextureLODGroups[GroupId].SetupGroup();
}

int32 UTextureLODSettings::CalculateLODBias(const UTexture* Texture, bool bIncCinematicMips) const
{	
	check( Texture );
	TextureMipGenSettings MipGenSetting = TMGS_MAX;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/TextureLODSettings.cpp:152

Scope (from outer to inner):

file
function     int32 UTextureLODSettings::CalculateLODBias

Source code excerpt:

int32 UTextureLODSettings::CalculateLODBias(int32 Width, int32 Height, int32 MaxSize, int32 LODGroup, int32 LODBias, int32 NumCinematicMipLevels, TextureMipGenSettings InMipGenSetting, bool bVirtualTexture ) const
{	
	checkf(LODGroup < TextureLODGroups.Num(), TEXT("A texture had passed a bad LODGroup to UTextureLODSettings::CalculateLODBias (%d, out of %d groups). This code does not have the texture name. The LODSettings object is '%s'"), LODGroup, TextureLODGroups.Num(), *GetPathName());

	// Find LOD group.
	const FTextureLODGroup& LODGroupInfo = TextureLODGroups[LODGroup];

	// Note: MaxLODSize sort of acts like a max texture size limit
	//	but it isn't really a good way to limit texture size
	// because there are various ways in which it can be ignored
	// eg. on textures set to NoMipmaps

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/TextureLODSettings.cpp:234

Scope (from outer to inner):

file
function     int32 UTextureLODSettings::CalculateNumOptionalMips

Source code excerpt:

	check( FPlatformProperties::RequiresCookedData() == false);

	const FTextureLODGroup& LODGroupInfo = TextureLODGroups[LODGroup];

	const TextureMipGenSettings& FinalMipGenSetting = (InMipGenSetting == TMGS_FromTextureGroup) ? (TextureMipGenSettings)LODGroupInfo.MipGenSettings : InMipGenSetting;
	if ( FinalMipGenSetting == TMGS_NoMipmaps)
	{
		return 0;
	}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/TextureLODSettings.cpp:253

Scope: file

Source code excerpt:


/**
* TextureLODGroups access with bounds check
*
* @param   GroupIndex      usually from Texture.LODGroup
* @return                  A handle to the indexed LOD group. 
*/
FTextureLODGroup& UTextureLODSettings::GetTextureLODGroup(TextureGroup GroupIndex)
{
	check(GroupIndex >= 0 && GroupIndex < TEXTUREGROUP_MAX);
	return TextureLODGroups[GroupIndex];
}

/**
* TextureLODGroups access with bounds check
*
* @param   GroupIndex      usually from Texture.LODGroup
* @return                  A handle to the indexed LOD group.
*/
const FTextureLODGroup& UTextureLODSettings::GetTextureLODGroup(TextureGroup GroupIndex) const
{
	check(GroupIndex >= 0 && GroupIndex < TEXTUREGROUP_MAX);
	return TextureLODGroups[GroupIndex];
}

#if WITH_EDITORONLY_DATA
void UTextureLODSettings::GetMipGenSettings(const UTexture& Texture, TextureMipGenSettings& OutMipGenSettings, float& OutSharpen, uint32& OutKernelSize, bool& bOutDownsampleWithAverage, bool& bOutSharpenWithoutColorShift, bool &bOutBorderColorBlack) const
{
	TextureMipGenSettings Setting = (TextureMipGenSettings)Texture.MipGenSettings;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/TextureLODSettings.cpp:292

Scope (from outer to inner):

file
function     void UTextureLODSettings::GetMipGenSettings

Source code excerpt:

	if(Setting == TMGS_FromTextureGroup)
	{
		const FTextureLODGroup& LODGroup = TextureLODGroups[Texture.LODGroup];

		Setting = LODGroup.MipGenSettings;
	}

	// angular filtering only applies to cubemaps
	// note: currently intentionally NOT allowed on cubearrays

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/TextureLODSettings.cpp:334

Scope (from outer to inner):

file
function     void UTextureLODSettings::GetDownscaleOptions

Source code excerpt:

void UTextureLODSettings::GetDownscaleOptions(const UTexture& Texture, const ITargetPlatform& CurrentPlatform, float& Downscale, ETextureDownscaleOptions& DownscaleOptions) const
{
	float GroupDownscale = FMath::Clamp(TextureLODGroups[Texture.LODGroup].Downscale, 1.0f, 8.0f);
	ETextureDownscaleOptions GroupDownscaleOptions = TextureLODGroups[Texture.LODGroup].DownscaleOptions;
	if (GroupDownscaleOptions == ETextureDownscaleOptions::Default)
	{
		GroupDownscaleOptions = ETextureDownscaleOptions::SimpleAverage;
	}
		
	Downscale = Texture.Downscale.GetValueForPlatform(*CurrentPlatform.IniPlatformName());

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/TextureLODSettings.cpp:367

Scope (from outer to inner):

file
function     const TextureMipGenSettings UTextureLODSettings::GetTextureMipGenSettings

Source code excerpt:

const TextureMipGenSettings UTextureLODSettings::GetTextureMipGenSettings(int32 InLODGroup) const
{
	return TextureLODGroups[InLODGroup].MipGenSettings; 
}



/**
 * Returns the filter state that should be used for the passed in texture, taking

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/TextureLODSettings.cpp:399

Scope (from outer to inner):

file
function     ETextureSamplerFilter UTextureLODSettings::GetSamplerFilter

Source code excerpt:

		default:
			// Use LOD group value to find proper filter setting.
			Filter = TextureLODGroups[Texture->LODGroup].Filter;
	}

	return Filter;
}

ETextureSamplerFilter UTextureLODSettings::GetSamplerFilter(int32 InLODGroup) const
{
	return TextureLODGroups[InLODGroup].Filter;
}


ETextureMipLoadOptions UTextureLODSettings::GetMipLoadOptions(const UTexture* Texture) const
{
	check(Texture);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/TextureLODSettings.cpp:420

Scope (from outer to inner):

file
function     ETextureMipLoadOptions UTextureLODSettings::GetMipLoadOptions

Source code excerpt:

	else
	{
		return TextureLODGroups[Texture->LODGroup].MipLoadOptions;
	}
}

#Loc: <Workspace>/Engine/Source/Runtime/SlateRHIRenderer/Private/SlateRHIRenderingPolicy.cpp:701

Scope: file

Source code excerpt:

	check(RHICmdList.IsInsideRenderPass());

	// Cache the TextureLODGroups so that we can look them up for texture filtering.
	if (UDeviceProfileManager::DeviceProfileManagerSingleton)
	{
		if (UDeviceProfile* Profile = UDeviceProfileManager::Get().GetActiveProfile())
		{
			if (Profile != LastDeviceProfile)
			{
				TextureLODGroups = Profile->GetTextureLODSettings()->TextureLODGroups;
				LastDeviceProfile = Profile;
			}
		}
	}

	IRendererModule& RendererModule = FModuleManager::GetModuleChecked<IRendererModule>(RendererModuleName);

#Loc: <Workspace>/Engine/Source/Runtime/SlateRHIRenderer/Private/SlateRHIRenderingPolicy.cpp:1399

Scope (from outer to inner):

file
function     ETextureSamplerFilter FSlateRHIRenderingPolicy::GetSamplerFilter

Source code excerpt:

	default:
		// Use LOD group value to find proper filter setting.
		if (Texture->LODGroup < TextureLODGroups.Num())
		{
			Filter = TextureLODGroups[Texture->LODGroup].Filter;
		}
	}

	return Filter;
}

#Loc: <Workspace>/Engine/Source/Runtime/SlateRHIRenderer/Private/SlateRHIRenderingPolicy.h:120

Scope (from outer to inner):

file
class        class FSlateRHIRenderingPolicy : public FSlateRenderingPolicy

Source code excerpt:

	TOptional<int32> InitialBufferSizeOverride;

	TArray<FTextureLODGroup> TextureLODGroups;

	UDeviceProfile* LastDeviceProfile;
};