如何在 sRGB space 中输入颜色值?
How do I input color values in sRGB space?
我正在学习 OpenGL 中的 sRGB 颜色 space。
一方面是来自纹理的颜色,另一方面是直接颜色值,比方说来自图形编辑器。
0.5 的颜色分量意味着屏幕上的输出将是较浅的颜色,187。
此处的最佳做法是什么 - 我是否必须在使用前通过计算根来解码颜色?
当使用 GL_SRGB8
或 GL_SRGB8_ALPHA8
内部格式指定纹理时,OpenGL 会在您对纹理进行采样时为您处理 sRGB 到线性的转换。对于所有其他颜色值(制服、顶点属性、清晰颜色等),您需要手动进行转换。
从 sRGB 到线性的转换很简单。您可以在 wikipedia 上查找函数并将其翻译成您喜欢的任何语言。例如在 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 个不同值的查找 table 可能会有所帮助。
请注意,尽早转换为线性很重要。例如。如果您将这些颜色作为插值顶点属性传递,那么您应该将线性值存储在 VBO 中,否则您将得到不正确的插值。
我正在学习 OpenGL 中的 sRGB 颜色 space。
一方面是来自纹理的颜色,另一方面是直接颜色值,比方说来自图形编辑器。
0.5 的颜色分量意味着屏幕上的输出将是较浅的颜色,187。
此处的最佳做法是什么 - 我是否必须在使用前通过计算根来解码颜色?
当使用 GL_SRGB8
或 GL_SRGB8_ALPHA8
内部格式指定纹理时,OpenGL 会在您对纹理进行采样时为您处理 sRGB 到线性的转换。对于所有其他颜色值(制服、顶点属性、清晰颜色等),您需要手动进行转换。
从 sRGB 到线性的转换很简单。您可以在 wikipedia 上查找函数并将其翻译成您喜欢的任何语言。例如在 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 个不同值的查找 table 可能会有所帮助。
请注意,尽早转换为线性很重要。例如。如果您将这些颜色作为插值顶点属性传递,那么您应该将线性值存储在 VBO 中,否则您将得到不正确的插值。