Advertisement

S3TC and gamma correction

Started by November 08, 2017 08:18 PM
3 comments, last by knarkowicz 7 years, 2 months ago

When utilizing S3 compressed textures, how is gamma correction handled? The resulting pixels from the offline tools appear to be mapped to values that should be linearly interpolated in the original sRGB gamma space. It has been suggested that the textures should be decompressed after gamma conversion, however, with the way that the compression is done, this does not seem right.

Suppose there is an uncompressed texture with samples that smoothly transition from 0 to 0.5 grey in gamma space within a 4x4 block. Compressing this to DXT1a would map the transitioning samples to that which is ~0.25 after decompression. If the texture is however first converted to linear space before this interpolation takes place, you'd have the explicit color values of 0 and ~0.22, and converting the interpolated ~0.11 back to gamma space would net you more than 0.35, which is far off from the 0.25 one would get from using a tool like nvcompress/nvdecompress.

The question is somewhat open ended as there as several factors to consider:

1. What color space is your DCC/Offline tool working in and how does it save the values into the input to the texture compression tool? That is a question only you can answer as we do not know what tool you use.

2. Is the texture compression tool gamma-aware ? Does it just blindly assume input values are linear and does the block compression on these values ? Again only a question you can answer as again the tool is your choosing. So you would have to dig into the manual/notes.

3. What texture format is was the S3TC created with ? If the texture was created with a non-SRGB format even though the image was indeed sRGB encoded, then the texture sampling hardware is going assume the texture is linear ( since that is how it was specified  ). Texture filter is a linear operation so the result is going to be incorrect as we are now doing linear operation on non-linear content.
If the texture was created with a sRGB format and if the hw supports it ( any modern GPU should do this correctly now ), then the texture sample will do the sRGB->linear conversion first, followed by filtering = correct result.


 

Advertisement

OpenGL's S3TC extension states that it allows for both behaviors (convert before decompress, or convert after decompress). The D3D documentation only says that conversion happens before filtering, so that also doesn't seem to make any guarantees. I'm not sure if Vulkan spec says anything on the matter.

HW interpolation doesn't work directly on BC data - first entire BC (S3) 4x4 block is decoded and stored in texture cache. BC decoding is obviously based on BC specs - so during BC decoding interpolation is always done in sRGB space. Next, filtering is done in linear space using values from texture cache (on post DX9 HW).

This topic is closed to new replies.

Advertisement