Control texture size in-game

How to control texture size (resolution), for example with low settings 1/4 of size, with medium 1/2 and with high full size.

yeah, this…
UE4 seems to favor relying only on the texture streaming pool size for this, which IMO is insufficient because once the texture pool gets filled you’ll start seeing super low-res textures next to the highest-quality ones that were already streamed in.

the documentation mentions using appcompat buckets but fails at everything beyond that- and it lies, since it doesn’t even work via the appcompat ini anymore.

if all you need is to limit your texture size for a specific platform (i.e. Android), simply go to DefaultDeviceProfiles.ini, find the category related to the platform and edit the default values for each texture group (no c++ code needed)
of course if you’re only shipping your game to a single platform it’s best to limit the texture sizes from within the texture itself, thus saving up on game file size

limiting the texture size on the fly is possible but you’re going to need c++ code for it, which feels like a step backwards compared to UE3 where it worked with a console command.
to do it on the fly here’s how:

  1. open DefaultDeviceProfiles.ini and add a device profile for every “texture quality” option that you want (i.e. High, Medium, Low). add the DeviceType and BaseProfileName lines and the all the texturegroups line like so:


	[Texture-Low DeviceProfile]
	DeviceType=AllDesktop
	BaseProfileName=
	+TextureLODGroups=(Group=TEXTUREGROUP_World,LODBias=0,NumStreamedMips=-1,MipGenSettings=TMGS_SimpleAverage,MinLODSize=1,MaxLODSize=512,MinMagFilter="aniso",MipFilter="point")
	+TextureLODGroups=(Group=TEXTUREGROUP_WorldNormalMap,LODBias=0,NumStreamedMips=-1,MipGenSettings=TMGS_SimpleAverage,MinLODSize=1,MaxLODSize=512,MinMagFilter="aniso",MipFilter="point")
	+TextureLODGroups=(Group=TEXTUREGROUP_WorldSpecular,LODBias=0,NumStreamedMips=-1,MipGenSettings=TMGS_SimpleAverage,MinLODSize=1,MaxLODSize=512,MinMagFilter="aniso",MipFilter="point")
*… and add all the other texture groups the same way]*

	[Texture-Medium DeviceProfile]
	DeviceType=AllDesktop
	BaseProfileName=
	+TextureLODGroups=(Group=TEXTUREGROUP_World,LODBias=0,NumStreamedMips=-1,MipGenSettings=TMGS_SimpleAverage,MinLODSize=1,MaxLODSize=1024,MinMagFilter="aniso",MipFilter="point")
	+TextureLODGroups=(Group=TEXTUREGROUP_WorldNormalMap,LODBias=0,NumStreamedMips=-1,MipGenSettings=TMGS_SimpleAverage,MinLODSize=1,MaxLODSize=1024,MinMagFilter="aniso",MipFilter="point")
	+TextureLODGroups=(Group=TEXTUREGROUP_WorldSpecular,LODBias=0,NumStreamedMips=-1,MipGenSettings=TMGS_SimpleAverage,MinLODSize=1,MaxLODSize=1024,MinMagFilter="aniso",MipFilter="point")
*… and add all the other texture groups the same way]*

	[Texture-High DeviceProfile]
	DeviceType=AllDesktop
	BaseProfileName=
	+TextureLODGroups=(Group=TEXTUREGROUP_World,LODBias=0,NumStreamedMips=-1,MipGenSettings=TMGS_SimpleAverage,MinLODSize=1,MaxLODSize=2048,MinMagFilter="aniso",MipFilter="point")
	+TextureLODGroups=(Group=TEXTUREGROUP_WorldNormalMap,LODBias=0,NumStreamedMips=-1,MipGenSettings=TMGS_SimpleAverage,MinLODSize=1,MaxLODSize=2048,MinMagFilter="aniso",MipFilter="point")
	+TextureLODGroups=(Group=TEXTUREGROUP_WorldSpecular,LODBias=0,NumStreamedMips=-1,MipGenSettings=TMGS_SimpleAverage,MinLODSize=1,MaxLODSize=2048,MinMagFilter="aniso",MipFilter="point")
*… and add all the other texture groups the same way]*

notice I added 3 groups: "Texture-Low", "Texture-Medium" and "Texture-High", which I limited to 512, 1024 and 2048 respectively
  1. make sure every texture in your project belongs to the right texture group for better granularity, so for example in low quality you might want to limit world textures to 512 but character textures to 1024 and so on
  2. in your c++ code, where your graphics settings menu exists (in the place where you change all other graphics settings), the function to apply the texture quality should look something similar to this:


	#include "IConsoleManager.h"
	#include "Engine/Texture.h"
	#include "Engine/Texture2D.h"
	#include "UObjectIterator.h"

	void someclass::ApplyTextureQuality(int quality)
	{
	static const auto CVarDeviceProfileOverride = IConsoleManager::Get().FindConsoleVariable(TEXT("dp.Override"));
	if (quality == 0)
	{
	 CVarDeviceProfileOverride->AsVariable()->Set(TEXT("Texture-Low"));
	}
	else if (quality == 1)
	{
	 CVarDeviceProfileOverride->AsVariable()->Set(TEXT("Texture-Medium"));
	}
	else
	{
	 CVarDeviceProfileOverride->AsVariable()->Set(TEXT("Texture-High"));
	}


	#if !WITH_EDITOR
	// properly refresh the textures in non-editor
	if (!IStreamingManager::HasShutdown())
	{
	 for (TObjectIterator<UTexture2D> It; It; ++It)
	 {
	  UTexture* Texture = *It;
	  Texture->UpdateCachedLODBias();
	 }
	}
	#endif

	UTexture::ForceUpdateTextureStreaming();

	}
	

this will update the device profile to use the new custom profiles with the limited texture sizes, and it will refresh all textures that are currently loaded to become limited as well
3 Likes

​​​​​​Thanks for reply!