TextureCompressionFormat
TextureCompressionFormat
#Overview
name: TextureCompressionFormat
The value of this variable can be defined or overridden in .ini config files. 1
.ini config file referencing this setting variable.
It is referenced in 7
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of TextureCompressionFormat is to specify an alternate texture compression format or plugin to be used in Unreal Engine 5. It is primarily used for the rendering system, specifically for texture compression and encoding.
TextureCompressionFormat is mainly relied upon by the texture compression and encoding subsystem of Unreal Engine. It is referenced in the TextureFormatOodle plugin and the TargetPlatform module.
The value of this variable is typically set in the Engine.ini configuration file under the [AlternateTextureCompression] section.
TextureCompressionFormat interacts with other variables such as TextureFormatPrefix and TextureCompressionFormatWithVersion. It also influences the behavior of texture compression settings like LossyCompressionAmount and various TextureLODGroups.
Developers must be aware that:
- This setting can significantly impact texture compression quality and performance.
- It may affect the engine’s behavior differently depending on whether textures are versioned or not.
- The setting can be platform-specific, so it may need to be configured separately for different target platforms.
Best practices when using this variable include:
- Ensure that the specified compression format module is available and compatible with your project.
- Test thoroughly to verify the impact on texture quality and performance.
- Consider using TextureCompressionFormatWithVersion for more granular control over versioned textures.
- Be mindful of the potential impact on build times and runtime performance when changing this setting.
- Coordinate with artists to find the right balance between texture quality and compression efficiency.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseEngine.ini:3440, section: [AlternateTextureCompression]
- INI Section:
AlternateTextureCompression
- Raw value:
"TextureFormatOodle"
- Is Array:
False
#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:56
Scope: file
Source code excerpt:
[AlternateTextureCompression]
TextureCompressionFormat="TextureFormatOodle"
TextureFormatPrefix="TFO_"
When this is enabled, the formats like "DXT1" are renamed to "TFO_DXT1" and are handled by this encoder.
Oodle Texture RDO encoding can be slow, but is cached in the DDC so should only be slow the first time.
A fast local network shared DDC is recommended.
RDO encoding and compression level can be enabled separately in the editor vs cooks using settings described
below.
========================
Oodle Texture Settings
----------------------
TextureFormatOodle reads settings from Engine.ini ; they're created by default
when not found. Note they are created in per-platform Engine.ini, you can
find them and move them up to DefaultEngine if you want them to be global.
The INI settings block looks like :
[TextureFormatOodleSettings]
bDebugColor=False
GlobalLambdaMultiplier=1.0
The sense of the bools is set so that all-false is default behavior.
bDebugColor :
Fills the encoded texture with a solid color depending on their BCN format.
This is a handy way to see that you are in fact getting Oodle Texture in your game.
It's also an easy way to spot textures that aren't BCN compressed, since they will not
be solid color. (for example I found that lots of the Unreal demo content uses "HDR"
which is an uncompressed format, instead of "HDRCompressed" (BC6)) The color indicates
the actual compressed format output (BC1-7).
GlobalLambdaMultiplier :
Takes all lambdas and scales them by this multiplier, so it affects the global default
and the per-texture lambdas.
It is recommended to leave this at 1.0 until you get near shipping your final game, at
which point you could tweak it to 0.9 or 1.1 to adjust your package size without having
to edit lots of per-texture lambdas.
Oodle Texture lambda
----------------------
The "lambda" parameter is the most important way of controlling Oodle Texture RDO.
"lambda" controls the tradeoff of size vs quality in the Rate Distortion Optimization.
Finding the right lambda settings will be a collaboration between artists and
programmers. Programmers and technical artists may wish to find a global lambda
that meets your goals. Individual texture artists may wish to tweak the lambda
per-texture when needed, but this should be rare - for the most part Oodle Texture
quality is very predictable and good on most textures.
Lambda first of all can be overridden per texture with the "LossyCompressionAmount"
setting. This is a slider in the GUI in the editor that goes from Lowest to Highest.
The default value is "Default" and we recommend leaving that there most of the time.
If the per-texture LossyCompressionAmount is "Default", that means "inherit from LODGroup".
The LODGroup gives you a logical group of textures where you can adjust the lambda on that
whole set of textures rather than per-texture.
For example here I have changed "World" LossyCompressionAmount to TLCA_High, and
"WorldNormalMap" to TLCA_Low :
[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);
#Loc: <Workspace>/Engine/Source/Developer/TargetPlatform/Public/Common/TargetPlatformBase.h:252
Scope (from outer to inner):
file
class class FTargetPlatformBase : public ITargetPlatform
function virtual void GetTextureFormatModuleHints
Source code excerpt:
// there is a possible optional format module name in the ini (alternate texture compressor)
FString TextureCompressionFormat;
if (GetConfigSystem()->GetString(TEXT("AlternateTextureCompression"), TEXT("TextureCompressionFormat"), TextureCompressionFormat, GEngineIni))
{
OutModuleNames.Add(*TextureCompressionFormat);
}
}
TARGETPLATFORM_API virtual FName GetWaveFormat(const class USoundWave* Wave) const override;
TARGETPLATFORM_API virtual void GetAllWaveFormats(TArray<FName>& OutFormats) const override;
#Loc: <Workspace>/Engine/Source/Developer/TargetPlatform/Public/Common/TargetPlatformControlsBase.h:170
Scope (from outer to inner):
file
class class FTargetPlatformControlsBase : public ITargetPlatformControls
function virtual void GetTextureFormatModuleHints
Source code excerpt:
// there is a possible optional format module name in the ini (alternate texture compressor)
FString TextureCompressionFormat;
if (TargetPlatformSettings->GetConfigSystem()->GetString(TEXT("AlternateTextureCompression"), TEXT("TextureCompressionFormat"), TextureCompressionFormat, GEngineIni))
{
OutModuleNames.Add(*TextureCompressionFormat);
}
}
TARGETPLATFORM_API virtual FName GetWaveFormat(const class USoundWave* Wave) const override;
TARGETPLATFORM_API virtual void GetAllWaveFormats(TArray<FName>& OutFormats) const override;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Texture.cpp:3430
Scope (from outer to inner):
file
function FName GetLatestOodleTextureSdkVersion
Source code excerpt:
// but to do that we need a target platform, since it could defer by target and not be set for current at all
// and here we need something global, not per-target
const TCHAR * TextureCompressionFormat = TEXT("TextureFormatOodle");
ITextureFormatModule * TextureFormatModule = FModuleManager::LoadModulePtr<ITextureFormatModule>(TextureCompressionFormat);
// TextureFormatModule can be null if TextureFormatOodle is disabled in this project
// then we will return None, which is correct
if ( TextureFormatModule )
{
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Texture.cpp:3471
Scope (from outer to inner):
file
function static FName ConditionalGetPrefixedFormat
Source code excerpt:
#if WITH_EDITOR
// "TextureCompressionFormat" specifies the Oodle Texture plugin to use for textures with OodleTextureSdkVersion == None
// versioned textures always use TFO
// TextureCompressionFormat can specify a pre-TFO plugin if desired
//
// if you want Oodle Texture encoding,
// TextureCompressionFormat is required, TextureCompressionFormatWithVersion is optional
FString TextureCompressionFormat;
bool bHasFormat = TargetPlatformSettings->GetConfigSystem()->GetString(TEXT("AlternateTextureCompression"), TEXT("TextureCompressionFormat"), TextureCompressionFormat, GEngineIni);
bHasFormat = bHasFormat && ! TextureCompressionFormat.IsEmpty();
if ( bHasFormat )
{
if ( ! bOodleTextureSdkVersionIsNone )
{
// new (optional) pref : TextureCompressionFormatWithVersion
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Texture.cpp:3492
Scope (from outer to inner):
file
function static FName ConditionalGetPrefixedFormat
Source code excerpt:
if ( bHasFormatWithVersion )
{
TextureCompressionFormat = TextureCompressionFormatWithVersion;
}
else
{
// if TextureCompressionFormatWithVersion is not set,
// TextureCompressionFormatWithVersion is automatically set to "TextureFormatOodle"
// new textures with version field will use TFO (if "TextureCompressionFormat" field exists)
TextureCompressionFormat = TEXT("TextureFormatOodle");
UE_CALL_ONCE( [&](){
UE_LOG(LogTexture, Verbose, TEXT("AlternateTextureCompression/TextureCompressionFormatWithVersion not specified, using %s."), *TextureCompressionFormat);
} );
}
}
ITextureFormatModule * TextureFormatModule = FModuleManager::LoadModulePtr<ITextureFormatModule>(*TextureCompressionFormat);
if ( TextureFormatModule )
{
ITextureFormat* TextureFormat = TextureFormatModule->GetTextureFormat();
if ( TextureFormat )
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Texture.cpp:3534
Scope (from outer to inner):
file
function static FName ConditionalGetPrefixedFormat
lambda-function
Source code excerpt:
{
UE_CALL_ONCE( [&](){
UE_LOG(LogTexture, Warning, TEXT("AlternateTextureCompression specified, Module found, but no TextureFormat : %s."), *TextureCompressionFormat);
} );
}
}
else
{
UE_CALL_ONCE( [&](){
UE_LOG(LogTexture, Warning, TEXT("AlternateTextureCompression specified but Module not found: %s."), *TextureCompressionFormat);
} );
}
}
#endif
return TextureFormatName;