1xRGB vs 3xR, which is better performing?

I have a lot of meshes that only require black and white basecolor in my scene. I was wondering if it is better performing (faster loading materials, less memory consumption) to have:

  • 1 texture with RGB data that can be split into basecolor, metallic, and roughness or
  • 3 textures that only have 1 channel data with 1 for each of basecolor, metallic, and roughness

I think loading may be faster on the 1 channel textures but there are 3 of them so do they take more memory?

Fewer textures is always better, so #1.

If you pack basecolor, metallic and roughness to single texture you need to be very carefull with compression. DXT1 compression assumes that rgb data is color and compress it using two end point colors and linearly interpolates between them in single 4x4 block. This mean that channels will bleed on others and cause nasty artefacts. So if you pack them single texture you can’t use compression. So you need to use rgba8888 texture. 32bit per texel. There is also problem that color need to be sRGB and metalness and roughness need to be in linear space.

I would store them on three separate texture. Base color without alpha on DXT1.(just use green channel to get 6bit precision.) For metalness and roughness use alpha(BC4). Total memory consumption is then 4 + 4 + 4 = 12 bits per texel. Also now can choose texture size per channel independently and save additional memory. Usually metalness map can be stored in half size. This will put memory consumption down to 4+4+1 =9.

Usually performance is dominated by memory bandwidth/cache not amount of texture reads.

You could create a scene with just two objects one with the RGB packed texture and one with the 3 one channel textures and use a GPU profiling tool(Links in my Sig) to see how the Driver/Graphics card handles it.
The driver may combine them together for performance, I don’t know if there are any D3D/OGL rules against that.


Just use “masks” compression.

Hmm. That seems only turn off the sRGB from sampler. But color values need to be in sRGB space but metalness and roughness does not.

If his basecolor only needs to be black and white then he can use the linear value and apply the srgb calculation on one channel himself it’s just a single line formula.

It’s does not work right if you have any kind of filtering or mipmaps.

‘Masks’ compression is specifically designed to keep the channels separate and stop any cross-talk, definitely pack them and use that!

Note that in doing so, you get less and less precision in the darker areas I’ve found. It doesn’t behave nicely with packed grayscale sprites for instance (for use with particles). I would suggest only using masks for Rough / Spec / AO / Metallic / various masks.

But there aren’t any single standard compression model that work for more thant two separate channels. BC5 has two channels and ue4 use that for normal maps. BC4 has single channel and that is used when you specify Alpha. BC2/3 has single color channel and single alpha channel. BC1 has single color channel.
So if it really works like you describe then UE4 would need to split texture to multiple textures or leave it as uncompressed. I looked a code and it just looked like it only disable sRGB but nothing more.

If there is some other infomation that I am unaware I like to know.