Packaging keeps breaking normal maps and I'm running out of ideas. Deploying to the same device, no issue. Why is this happening?

I’m just starting a new UE 5.3 Android project, and every time I try to package content / side load it, the normal maps break, but if I deploy straight from the editor to the same device, no issue, looks perfect.

I have tried a lot of things, different textures (starter content included), different models / primitives, different lighting. I’ve tried turning off package compression. I have no idea what other things to try, I’m just left clicking everything in the package settings at this point.

I don’t want to remove the normal maps of every object I will use. There has to be a reason this is happening, but I’m stumped.

How it should look (and does when deploying to device):

And this is how it looks on the same device package, side loaded, broken:

My device is a “Pixel 6 Pro” running Android 14. I followed the normal setup for android as the usual documentation. I had a “Storage Permission Required” issue I solved with this post, but other than that, most of the settings are out of the box. I have specified the map to package (which there is only one) and I don’t package editor content.

Does anyone have any ideas or suggestions on what might be going wrong here? I’m out of ideas.

Hi, have you found a solution for this? I am having the same issue since UE 5.3 on Android, and the issue remains with 5.4. Tested with OnePlus 7 Pro & OnePlus 12

Edit: I’ve also found your reddit post about this topic where someone says it’s a engine bug and following code should can fix it:
In C:\Program Files\Epic Games\UE_5.4\Engine\Source\Developer\Android\AndroidTargetPlatformSettings\Public\AndroidTargetPlatformSettings.h, add under public:

	bool SupportsFeature(ETargetPlatformFeatures Feature) const override
	{
		//FAndroid_MultiTargetPlatformControls::GetTextureFormats() replaces NormalLA for NormalRG
		//So we disable the feature support to ensure shaders rebuild the blue channel correctly (See: LA_NORMALMAPS)
		if (Feature == ETargetPlatformFeatures::NormalmapLAEncodingMode)
		{
			return false;
		}
		return FAndroidTargetPlatformSettings::SupportsFeature(Feature);
	}

From: https://github.com/EpicGames/UnrealEngine/pull/11615/files

From what I understand, it has to do with the difference between how DirectX and OpenGL handle the normal map green channel. The DirectX normal maps use an inverted green channel, so they will look wrong unless manually inverted.

I found that packaging in Multi format or DXT format will require the inverted green channel. I have no idea how to easily invert the channel for DirectX use, so I’m just sticking with OpenGL packaging (ASTC and ETC2). Even if I remove DXT from the packaging and package for Multi, it still requires the inverted green channel in the normal map. No idea why.

See if this video helps on how to flip the green channel: