Using red and green channels as normal map and using blue as mask?

Some problems in the post. DXT1 does not have alpha channel.(there is 1bit alpha channel mode but it’s not supported by engine.) When using rgba texture with default compression it’s using DXT5.
Your normal map encoding is dead wrong. Result is not unit length. Correct way is to use DeriveNormalZ node.(but there is actually bug in the 4.18 so I just use this custom node.



MaterialFloat NormalZ = sqrt(saturate(1.0f - dot( NormalXY, NormalXY) ) );
    return MaterialFloat3(NormalXY.xy, NormalZ);


This is what engine does underhood when using NormalMap compression combined with BC5 compression.(just two channel version of BC4 which is same as alpha channel of dxt5).

Problem with combining other channels with normal map is that you get different quality for x and y. Your method is giving almost perfect quality for y channel but x channel is garbage. Where y channel do get 8-bit endpoints and 8 interpolated values between those. X is getting only 6-bit endpoints and 4interpolated values between those. Also x is getting cross channel talk from roughness and metallic.

This is actually really good advice. When using separate textures for separate needs you can reason about texture size a lot more. When there is less artifacts from compression you also can use a lot smaller textures.
Usually I can use 1/4 texture size for metallic map(BC4/Alpha) and emissive.(DXT1). Ambient occlusion is 1/2 or 1/4.
So when you can trust that you get good quality compression you get bigger savings from choosing texture sizes per usage.

2 Likes