Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
485 views
in Technique[技术] by (71.8m points)

color profile - sRGB Conversion OpenGL

Let's say I load a texture from a jpg file that has the sRGB color profile and while loading there was no conversion to a linear RGB. When a rect is displayed on screen I don't see any problems with image. the color is the same as opening it in one of the editors.

The question, since there was no conversion the RGB values remained in sRGB range. How does hardware know that no conversion is needed or why it was not converted by the GPU. Basically why XYZ -> sRGB conversion didn't happen.

I am very confused since if I feed sRGB data into something that shall in the end convert it to sRGB again will change colors, but it doesn't.

question from:https://stackoverflow.com/questions/65831143/srgb-conversion-opengl

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First of all, OpenGL does NOT do any color conversion by default. Let's start from the smallest configuration, consisting of an Input Image, Window Buffer (rendered by OpenGL) and a Monitor. Each might be defined by different color space, but in simplest case it will look like that:

[RGB image|sRGB] -> [OpenGL Window Buffer|sRGB] -> [Monitor|sRGB]

By default, monitors are configured to use an sRGB preset, even the ones supporting a wider color range, to avoid incorrect color output. Rendering into OpenGL Window Buffer by default doesn't perform any color conversion, so that if input image was in sRGB colorspace it will remain the same in OpenGL Window Buffer. OS Composer normally just copies OpenGL Window Buffer onto the screen - no color conversion is implied at this step too. So basically all steps just pass-through input image and you see result as expected if it was in sRGB colorspace.

Now consider another scenario: you are applying Input Image for texture-mapping onto 3D object with lighting enabled. Lighting equation makes sense only in linear RGB colorspaces, so that without extra configuration OpenGL will basically take non-linear sRGB image values, pass them as parameters to shading equations unmodified and write result into OpenGL Window Buffer, which will be passed-through to Monitor configured to sRGB colorspace. The result will be affordable, but physically incorrect.

To solve the problem with incorrect lighting, OpenGL has introduced sRGB-awareness features, so that user may say explicitly if Input Image is in sRGB or linear RGB colorspace and if result of GLSL program color values should be implicitly converted from linear RGB colorspace into non-linear sRGB colorspace. So that:

[GLSL Texture Input|sRGB -> linear RGB implicit conversion] ->
 -> [GLSL Lighting Equation|linear RGB] ->
 -> [GLSL output|linear RGB -> sRGB implicit conversion]

The steps with implicit conversion will be done ONLY if OpenGL has been explicitly configured in that way by using GL_SRGB8_ALPHA8 texture format and by using GL_FRAMEBUFFER_SRGB while rendering into offscreen or Window Buffer. The whole conception might be tricky to understand and even trickier to implement.

Note that in this context "linear RGB" actually means linearized sRGB colorspace, as it is often omitted what linear RGB actual means. This is because for color math (lighting and other) it is important only that RGB values are linear on input and output in any linear colorspace, but when speaking about implicit sRGB -> linear RGB and linear RGB -> sRGB conversion - these clearly rely on conversion of RGB values defined by sRGB and OpenGL specifications. In reality, there are more linear RGB colorspaces which do not represent sRGB colorspace.

Now consider that your Input Image is not in sRGB colorspace, but using some another RGB color profile. OpenGL doesn't give much other texture formats save linear RGB and sRGB, so that a proper conversion of such image into sRGB colorspace should be done by image reader or via special GLSL program performing colorspace conversion on-the-fly.

Now consider a Monitor being configured to non-sRGB profile like AdobeRGB. In this case passing-through sRGB image to OpenGL window will produce distorted colors. By letting Windows know that your monitor in another color profile you will help some applications like Photoshop to convert colors properly, but OpenGL knows nothing about these color profiles configured in Windows! It is an application that is responsible to apply color profile information to perform a proper color transformation (via special GLSL programs or by other means). By working with an Input Image in non-sRGB colorspace application will have also an alternative to perform non-sRGB -> sRGB -> another non-sRGB color conversion or to implement GLSL program which will perform color conversion without proxy sRGB (or via proxy XYZ) directly to target colorspace to avoid losses of color precision information due to transient conversions.

Supporting arbitrary color profiles in OpenGL viewer not designed to be an image viewer might involve too much complexity. Some systems, however, define several standard color spaces to perform implicit conversion by system composer - which is much more reliable than supporting arbitrary color profiles with their special lookup tables and formulas.

For instance, macOS defines NSWindow::setColorSpace property which allows application to specify explicitly in which colorspace Window Buffer is filled in, so that system itself performs necessary conversion to actual Monitor color profile. Android system defines a similar interface for supporting a new P3 Display color profile with an extended color range compared to the old sRGB color profile. This implies, however, that OpenGL renderer actually knows how to output result in this specific colorspace - which is another topic (there are also a set of extra OpenGL extensions helping developers in this direction)... So far I haven't heard about a similar API in Windows, but I might be missed something.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...