google / gapid

Graphics API Debugger
https://gapid.dev
Apache License 2.0
2.2k stars 327 forks source link

Better UI support for sRGB textures. #1055

Open pmuetschard opened 7 years ago

pmuetschard commented 7 years ago
dsrbecky commented 6 years ago

TL;DR: We render the right thing now, please let's not change it (the status bar text might need some tweaking). There is no need for toggle.

My long standing option is that all non-float textures are sRGB.

When you work with 8-bit colours in computers, it pretty much always implies sRGB, whether it is stored on disk, in memory, or pixels in on screen buffer. Thus, just taking the 8-bit colour and rendering in the client as-is is always the right thing to do. There is no conversion needed for rendering RGB8.

On the other hand, HDR textures always need conversion from liner-space float to the sRGB-space 8-bit to be rendered on screen, and we also need the histogram to choose the range to represent.

So if things are so simple, why does the spec even mention sRGB? That is because doing arithmetic on sRGB values (blending, lighting, etc...) is generally not valid as it is in log-space! People often ignore that fact, as it still looks-kind-of-ok and it is faster not to convert (think of your average UI framework... do you really care?) . That is 99% of computer software. But people, who care, need to do arithmetic in liner-space, which means converting inputs to shaders from sRGB to linear, and then converting outputs from linear to sRGB.

Those two conversions (in and out) are pretty simple, but it is in fragment shared, and involves SFU instructions... so actually pretty costly. That is why the GPUs has dedicated logic to do this automatically in hardware (where property of the texture/sampler turns on/off the hardware input converter, and property on the framebuffer turns on/off the hardware output converter). You can obviously turn of the hardware converter, and do the conversion yourself in the shader - it is more costly, but equivalent. So all of the sRGB fluf in the spec is just a way to add some hardware assisted fast conversions in the shaders, it does not really affect how we should render textures/framebuffers on screen. 8-bits are always sRGB, simple.

Important sidenote on the api state control:

So what we render in texture view and framebuffer view is always clearly defined, and we currently do the right thing. Yay. The only question is, when you hover over a pixel, what do you show in the status bar? The 8-bit values are always sRGB regardless of any GL state or texture format. Simple. But what do you show? The #428042 raw-byte format is unambiguous, but should the printed floating point value be just the trivial (byte/255.0), or should it be the linear-space-converted floating point?

My conclusion is:

That was a bit longer comment then expected :-D