Skip to content

A quick script to generate sRGB to linear or linear to sRGB LUT for when GL_SRGB is not available.

License

Notifications You must be signed in to change notification settings

WARP-LAB/srgb-linear

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LUT for sRGB to linear or vice versa conversion

About

When

  • you want to receive data in linear colour space in your texture lookups (as you should ^_^)
  • but you can't because your crappy SBC OpenGL ES on EGL implementation does not have GL_SRGB internal format
  • your texture is not floating point
  • and you want to avoid converting sRGB to linear colour space in shader for every fragment

then apply LUT to image data before giving it to glTexImage2D while still keeping internal format specified as GL_RGB(A).

Or vice versa.

Generation

Edit generate.js to choose which mapping function to use.

Generate output file lut.hpp

node generate.js > lut.hpp

See attached lut.hpp.

Usage

Say you are using stb_image

int stbiWidth, stbiHeight, stbiNoChannels;
unsigned char *stbiData;
stbiData = stbi_load(pathToImage.c_str(), &stbiWidth, &stbiHeight, &stbiNoChannels, 0);

if (stbiData == nullptr) {
	// throw std::runtime_error ...
}

GLint internalFormat = GL_RGB;
GLenum format = GL_RGB;

// populate mapped float array, edit raw image data, convert from sRGB to linear
std::vector<float> stbiDataF;
unsigned int stbiCount = stbiWidth * stbiHeight * stbiNoChannels;
for (unsigned int pIdx = 0; pIdx < stbiCount; pIdx += stbiNoChannels) {
    for (unsigned int cIdx = pIdx; (cIdx < pIdx + stbiNoChannels && cIdx < pIdx + 3); cIdx++) {
        stbiDataF.push_back(lut_srgb_to_linear_f[stbiData[cIdx]]);
        stbiData[cIdx] = lut_srgb_to_linear_8[stbiData[cIdx]];
    }
}

// feed to gpu (preferably float if you have OES_texture_float extension available)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, stbiWidth, stbiHeight, 0, format, GL_FLOAT, stbiDataF.data());

// but you can still use unsigned bytes
// just note the precission loss in space conversation (see first 15 bytes of lut_srgb_to_linear_8)
// glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, stbiWidth, stbiHeight, 0, format, GL_UNSIGNED_BYTE, stbiData);

stbi_image_free(stbiData);
stbiDataF.clear();

For floating point textures do conversation on the fly.

Profit.

About

A quick script to generate sRGB to linear or linear to sRGB LUT for when GL_SRGB is not available.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published