首页 > 解决方案 > 如何在 sRGB 空间中输入颜色值?

问题描述

我正在学习 OpenGL 中的 sRGB 颜色空间。

一件事是来自纹理的颜色,但其他 - 直接颜色值,让我们说来自图形编辑器。

颜色分量 0.5 意味着屏幕上的输出将是较浅的颜色,即 187。

这里的最佳做法是什么 - 我是否必须在使用前通过计算根来解码颜色?

标签: openglcolorsgammasrgb

解决方案


当纹理使用内部格式指定时,GL_SRGB8OpenGLGL_SRGB8_ALPHA8会在您对纹理进行采样时为您处理 sRGB 到线性转换。对于所有其他颜色值(制服、顶点属性、清晰颜色等),您需要手动进行转换。

从 sRGB 到线性的转换很简单。您可以在维基百科上查找该功能并将其翻译成您喜欢的任何语言。例如在 C 中:

float srgb_to_linear(float x) {
    return x <= 0.04045f ? x / 12.92f : powf((x + 0.055f)/1.055f, 2.4f);
}

这会将 [0,1] 范围内的 sRGB 的一个分量转换为 [0,1] 范围内的线性。要像大多数图形编辑器向您展示的那样从 8 位 sRGB 转换,请将每个组件除以255.,然后将上述函数应用于每个组件:

void srgb8_to_linear(uint8_t in[3], float out[3]) {
    for(int i = 0; i < 3; ++i)
        out[i] = srgb_to_linear(in[i]/255.f);
}

如果性能很重要,那么预先计算所有 256 个不同值的查找表可能是有益的。

请注意,尽早转换为线性很重要。例如,如果您将这些颜色作为插值顶点属性传递,那么您应该将线性值存储在 VBO 中,否则您将得到不正确的插值。


推荐阅读