Does GPU mipmapping assume the texture es gamma corrected?

I have been reading the Real Time Rendering book and stumbled upon this paragraph:

For textures encoded in a nonlinear space (such as most color textures), ignoring gamma correction when filtering will modify the perceived bright- ness of the mipmap levels [121]. As you get farther away from the object and the uncorrected mipmaps get used, the object can look darker overall, and contrast and details can also be affected. For this reason, it is impor- tant to convert such textures into linear space, perform all mipmap filtering in that space, and convert the final results back into nonlinear space for storage.

I have never taken into account gamma correction for color textures using mipmapping.

For generating mipmaps I have always used the GPU-implementation (OpenGL):

glGenerateMipmap


In the resources I have learned from, gamma correction has not been mentioned as something that has to be taken into account for mipmapping.

I was wondering, since color textures that include gamma correction seem to be the norm, are the GPU-provided filtering functions already taking into account gamma correction?

• This sounds like something you could test for yourself: make a test pattern with lots of adjacent bright/dark regions, save & import as an sRGB texture. Generate mipmaps using your most familiar method. Inspect the resulting texel values of the mips, and compare against the expected values you computed by hand using linear and gamma space intermediates. Which one matches? – DMGregory Nov 13 '19 at 22:28
• This answer on StackOverflow deals with how sRGB textures are dealt with by OpenGL, including how they're filtered, but doesn't address mipmap generation specifically: stackoverflow.com/questions/10347995/… – Ross Ridge Nov 14 '19 at 1:54

Taking from the OpenGL 4.4 specification:

The contents of the derived arrays are computed by repeated, filtered reduction of the levelbase array. For one- and two-dimensional array and cube map array textures, each layer is filtered independently. No particular filter algorithm is required, though a box filter is recommended as the default filter.

So we can see that this is farily weakly-specified, and details of how submips are filtered are left up to the implementation.

In other words: if you require gamma-correction you can't make any assumptions about how, or even if, your GL implementation will do it, so you will need to write your own miplevel reduction in software.

I wanted to share some tests I made.

So we have this image (800x600px):

And we are going to downscale it to 400x300px in 3 different ways

1) Simple box filter, in CPU

2) Undo gamma correction -> box filter -> redo gamma correction, in CPU:

3) Just use the second level of GPU mipmapping (OpenGL)

All the images look quite similar to me and, in fact, I can't really tell the difference when I switch between them.

So I made a little program to measure the difference between images. I just sum the absolute value difference for each pixel for each channel.

And these are the results:

1) - 2) : 516.270264
1) - 3) : 769.195129
2) - 3) : 336.302246


So, at least in my PC, the GPU mipmapping seems to be quite different from the "correct" box filter method. But that could be just because the GPU is using a completely different downsampling method.

Test specs: OpenGL 3.3, Ubuntu 18.04, Nvidia 960M

• Gamma correction mostly influences downsampling of images with high-contrast transitions, e.g. of a non-antialiased black-and-white images like this test example. With it I get the following results from your code: ./compare_images mipmapping.png bad.png17.105667, and ./compare_images mipmapping.png good.png1990.272339. This is on my GeForce GTX 750Ti. I suppose most if not all GPUs will behave the same: no gamma correction, unless the format implies that it's gamma corrected (like the GL_SRGB8 format). – Ruslan Jan 4 at 16:14