Automated RGB Channel Swapping

This isn’t strictly unreal specific, but I’m hoping someone has run into this problem I’ve encountered and solved it.

I have a bunch of texture images that for consistency’s sake I would like to swap the Red and Green channels around, because currently half my textures are using Red for Metallic and Green for roughness, and the other half are using Red for Roughness Green for Metallic. Is there a way to script or automate this using anything? Substance, Photoshop, something else? Or do I just have to do it manually?


You could probably write a Photoshop action that does this very quickly, or find somekind of scriptable image editor and export then reimport all the assets.

I always use Red for Metalness, Green for roughness (green has slightly more detail in DXT compression, and roughness is the most important part usually) and Blue for AO.

^^ as blue is the one with the least detail in DTX, wouldn’t it make sense to use blue for metalness and red for AO?

You can swap them for whatever makes sense for your project and art style. Since the contrast between metal and non metal is so drastic, compression artifacts would work worse on metalness than AO.

But if a material doesn’t need a metal channel, you can always use it for something else.

A little off topic, would it be possible combine normal map (2 channels) + ao (1 channel) in a single texture? Probably wouldn’t play nice with the standard compression…

To get higher quality normal maps with fewer artifacts UE4 compresses Normal maps using the BC5 compression method. Unfortunately, BC5 blows away the Blue and Alpha channels so you can not store anything inside of them. However you can use DXT 1 compression which could have some blockey artifacts but will allow you to store addational info in your Normal maps. To see how to set this up check out the following blog post.

Hey guys, thanks so much, seems like a Photoshop action should do the trick, I will look into that.

Quick extra question. I have some asset packs that I bought on the marketplace, and I want to export some of the textures so I can combine the channels to save memory, etc. I bulk export the textures, but for some reason, some of them export as .TGAs and others as 1kb .T3D files that are essentially useless. Is there no way to get those specific ones out into a recognisable image file?

Well… I tried, seems like it can not be done. The tiniest artifact caused by DXT1 is enough to throw the shader off so much that it just looks like complete garbage.

I just did a test with to see if this was broken and I did get this to work with only slight artifacts/detail loss when using DXT1 verses BC5. Here are some images that show the results of my test.

DXT 1 Compression

BC5 Compression

There is a slight difference between the two but it is kind of hard to tell. I am sure that other normal maps might break down even more than what I used. IMO the artifacts that I am seeing in this small test more than justify the 4 instruction per Material that you would be saving, especially in something like a mobile/mobile VR project. THe other cool thing about this is that since you do this on a Material by Material basis you could in theory use this on the enviroment objects and then use the standard normal workflow on other items that the player interacts with.

I tried it with this texture from my project.
R/G for the normal and B for the ao is correct, right?

This is how it ends up in the world normal buffer:

And this is what the shader outputs:

Seems like it is extremely sensitive to those barely visible compression artifacts.

Did you re-create your blue channel in the Material? From your last image, it looks like you are missing that info or it is backward, not entirely sure.

I thought the blue channel is not used at all for normal maps? I just dragged the white pin of the texture to * 2 - 1 like in your example, and connected the blue to ao.

Let me try a similar example to yours to see if I can give you some better advice on how to fix thus. Also the blue channel can be used to store height data for your normal map.

Connect the white pin to a mask node to use only the first two channels of the texture. You’re currently sending the ‘AO’ channel to the Normal input as the Normal Z. You’ll also want to add a ‘Derive Normal Z’ node to the chain just before you plug it into ‘Normal’ too.

Oh! So when the sampler node is set to “normal” mode, that implies a “derive normal z”? Makes sense.

…it’s still kind of garbage though.
This is with normal and ao separate:
And this is with normal and ao combined:

The material:
Having the ao in the B channel seems to introduce artifacts in the other channels… really strange.

Yeah there is some cross-talk between channels during compression IIRC, so it might not work that well in all cases… I prefer to keep Normals separate personally.

I tried this again, this time using something with a way less noise in it but I am not seeing the same level of artifacts that you are. Would you mind posting your Texture so I can play around with them? Testing with content that is similar to your gives me the following:

I do have a few artifacts in mine, which is to be expected, but the artifacts I see are not as pronounced as the ones you have which is quite puzzling. Granted it is only 9:30 in the morning so my not fully caffeinated brain might be missing something that is painfully ovbious. But in any case, if you post your testing Normal, I might be able to figure out what needs to be done to fix it.

This is the one I tested:

Created it in gimp by combining these 2:

I can see fairly heavy stairs-like artifacts in your example aswell, though:

The stair stepping you are seeing is from my laziness in finding content to quickly test with :). I just took a random 256 x 256 Texture I had and scaled it to fit the 1024 x 1024 UE4 Logo Normal map so that is why you are seeing the artifacts thoes artifacts. I was able to get a little better quality in the normal map you posted by re-normalizing it in Photoshop but there are still artifacts which is to be expected when using DXT. IMO if you use this method on small environment objects or things that have noisy Base Color textures that would help to mask the artifacts in the Normal IMO. I also noticed that the AO had less issues if I ran a small blur on it to smooth out some of the pixels and make things less blocky.