Tales of Multiply Map and Gamma Correction

Pope Kim Feb 18, 2015

Using a detail map, or multiply map, on top of diffuse map is a somewhat popular way to eliminate the repeating pattern on tiled textures.

I've once implemented this upon an artist's request. The actual blend(?) math I used was:

DiffuseMap * MultiplyMap * 2

The reason I added * 2 at the end was to also give a detail map the ability to brighten the diffuse map. (without this, it can only darken the base map.) So the idea was if an artist paint a detail map with half grey, or 0.5, it wouldn't change the base diffuse map at all.

It had worked fine until we decided to change our rendering engine to "gamma-aware". While we were enabling sRGB texture read on certain textures, we accidentally did it on detail maps, too. Then, a month or two passed by, and a few assets were made with this new "gamma-powered" shaders.

Then a "tech-driven" artist found out painting a detail map with the value of 0.5 darkens the texture instead of keeping the base color. OMG. This was because our new blending formula looked like this:

{ (DiffuseMap ^ 2.2) * (MultiplyMap ^ 2.2) * 2 } ^ (1/2.2)

Because of power of 2.2, it makes 0.5 smaller than 0.25 and multiplying this by 2 gives you a value less than half intensity, 0.5. So I had to fix it by disabling sRGB read on multiply maps. And this is how the blending looks like now:

{ (DiffuseMap ^ 2.2) * MultiplyMap * 2 } ^ (1/2.2)

Better, eh?

Then, I asked artists to change detail maps authored with previous shaders to comply with our new way. To me, converting them was very straightforward.

  1. Open a detail map in PhotoShop.
  2. From main menu, select Image > Adjustment > Exposure.
  3. Set gamma to 0.454545(same as 1 / 2.2).
  4. Press OK

But this time a "visually-driven" artist wanted to change base diffuse maps instead of detail maps because gamma-ing details maps makes them too dark, so it's hard to work with. He asked me what's the easiest way to do this. Unfortunately, I couldn't find a mathematically correct way that always produces the correct conversion, so he had to manually change them while visually verifying the result.

This was probably one of the few cases where mathematical correctness can make things easier than harder, but unfortunately I was not able to find the magic formula. I just don't think it's possible here.

Am I just stupid? Does anyone know the correct math here?