Can't Generate LODs for 8192x8192 Normal Textures.

I think I’ve discovered a bug trying to generate mipmaps for a normal texture 8192x8192.

Reproduction steps:

1, create a project with a DefaultDeviceSettings.ini file in the config folder with the following settings

[/Script/Engine.TextureLODSettings]
TextureLODGroups=(Group=TEXTUREGROUP_World,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_WorldNormalMap,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_WorldSpecular,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Character,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_CharacterNormalMap,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_CharacterSpecular,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Weapon,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_WeaponNormalMap,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_WeaponSpecular,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Vehicle,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_VehicleNormalMap,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_VehicleSpecular,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Cinematic,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Effects,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=linear,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_EffectsNotFiltered,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Skybox,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_UI,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Lightmap,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Shadowmap,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,NumStreamedMips=3,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_RenderTarget,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_MobileFlattened,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Terrain_Heightmap,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Terrain_Weightmap,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Bokeh,MinLODSize=1,MaxLODSize=256,LODBias=0,MinMagFilter=linear,MipFilter=linear,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Pixels2D,MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=point,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)

(That + sign must be missing from the first line in order to work)

2, Import an 8192x8192 normal texture

3, Open the texture and notice the “Combined LOD Bias” increases to 1, and as a result the displayed resolution below is 4096x4096

4, If you change the texture group to world you’ll see that it works properly, however the texture will appear as a solid purple color. In order to fix this you have to change the compression setting to default.

5, If you go through the rest of the groups you’ll see the following results

World              -8192
WorldNormalMap     -4096
WorldSpecular      -8192
Character          -4096
CharacterNormalMap -4096
CharacterSpecular  -8192
Weapon             -8192
WeaponNormalMap    -4096
WeaponSpecular     -8192
Vehicle            -4096
VehicleNormalMap   -4096
VehicleSpecular    -8192
Cinematic          -4096
Effects            -8192
EffectsNotFiltered -8192
Skybox             -4096
UI                 -8192
Lightmap           -4096
Shadowmap          -8192
RenderTarget       -4096
MobileFlattened    -8192
Terrain_Heightmap  -4096
Terrain_Weightmap  -8192
Bokeh              -4096
2D Pixels          -4096

Further, if you change the Mip Gen Settings to NoMipMaps, you will see that the Displayed size for all of these broken groups will show as 8192, but the Max In-Game will still show 4096.

I suspect two things happened here:

When implementing 8192x8192 texture support the devs noticed that the normal compression algorithm in DX11 (And possibly others) wouldn’t support the larger textures.

As a workaround they set it up somehow so that on those groups it automatically increases the LOD Bias to prevent the issue.

Questions I have

  1. Is this a known bug, and is my understanding of what’s happening here correct?

  2. If this workaround must live on in the code, wouldn’t it be better to increase the CombinedLODBias when you’re on a bad compression setting, rather than a particular texture group?

  3. Couldn’t a different workaround be developed that used a different compression setting for the highest LOD? Or does all of this LOD generation happen in a black box within DX11?

  4. If this is a DX11 issue, will DX12 support these larger textures?

Hi Tom,

I’m not seeing anything specifically wrong in my setup when I adjust the max texture resolution.

  • I’ve used the in editor tool to generate my device profile by going to Window > Developer Tools > Device Profiles.
  • Then I click on the Save As Default button in the top right. Then if I go back to my Project Folder > Config I’ll find a DefaultDevicesProfile.ini file.
  • When I open this and adjust the MAXLODSize to be 8192, save and then restart the editor everything loads for my diffuse and normal map.

My normal map doesn’t have a purple look to it. It looks as though I would expect.

-Tim

This issue has resolved itself for me after I changed machines. My old machine was using a 900 series TitanX extreme edition, while my new machine is using a gtx 1080. I don’t have time to go back and triple check everything, but I currently suspect that my hardware was the issue. If anyone else encounters this, I would start there.