Skip to content

renderer: implement native sRGB support#1687

Merged
illwieckz merged 3 commits intomasterfrom
illwieckz/srgb-native
Aug 1, 2025
Merged

renderer: implement native sRGB support#1687
illwieckz merged 3 commits intomasterfrom
illwieckz/srgb-native

Conversation

@illwieckz
Copy link
Member

@illwieckz illwieckz commented Jun 25, 2025

Implement native sRGB support.

Obsoletes #1543:

It includes the commit from #1686:

This is based on an even older branch from 2019 as I initially tested native sRGB support before attempting to implement it in GLSL.

I rebased on current master and merged improvements from the srgb-naive branch as it implemented more corner cases than this one.

It still suffers from the problems I faced in 2019: 2D colors are wrong. I need help on that part.


Status:

color source conversion implemented when is converted how is converted
color map ✅️ sampling metadata
diffuse map ✅️ sampling metadata
glow map ✅️ sampling metadata
specular map ✅️ sampling metadata
animMap ✅️ sampling metadata
skybox ✅️ sampling metadata
light map ✅️ sampling metadata
light grid ✅️ loading conversion
map tris vertex color ✅️ loading conversion
map patch vertex color ✅️ loading conversion
expression_t ✅️ uploading conversion
CGEN_CONST ✅️ uploading conversion
CGEN_WAVEFORM ✅️ uploading conversion
CGEN_ENTITY ✅️ uploading conversion
CGEN_ONE_MINUS_ENTITY ✅️ uploading conversion
polyVert_t::modulate ✅️ uploading conversion

@illwieckz illwieckz added A-Renderer T-Feature-Request Proposed new feature labels Jun 25, 2025
@illwieckz illwieckz force-pushed the illwieckz/srgb-native branch 2 times, most recently from c914db4 to ce0a6e3 Compare June 25, 2025 07:46
@illwieckz
Copy link
Member Author

illwieckz commented Jun 25, 2025

Hmmm… I don't know where to write the line glEnable( GL_FRAMEBUFFER_SRGB );, should it be called at the beginning of every frame?

Edit: Nowhere, it should not be used in our case.

@VReaperV
Copy link
Contributor

Hmmm… I don't know where to write the line glEnable( GL_FRAMEBUFFER_SRGB );, should it be called at the beginning of every frame?.

You only really need to call it once, it's global state and will affect all sRGB framebuffers.

@illwieckz
Copy link
Member Author

Which framebuffer should be sRGB there?

@illwieckz illwieckz force-pushed the illwieckz/srgb-native branch from ce0a6e3 to 387cac8 Compare June 30, 2025 17:41
@illwieckz
Copy link
Member Author

As a matter of fact, I have zero confidence this implementation is correct, unlike the GLSL alternative implementation.
I expect this to be wrong because I lack some understanding of how sRGB stuff are done the OpenGL way.

Said otherway, I know how to implement the whole computation myself in GLSL, but I don't know how to configure OpenGL to let it do the computation by itself without me writing the explicit computation.

The GLSL implementation is a math algorithm, the OpenGL implementation is a puzzle.

@illwieckz illwieckz force-pushed the illwieckz/srgb-native branch from 387cac8 to feee7ff Compare July 6, 2025 00:45
@illwieckz
Copy link
Member Author

@VReaperV what is expected if I, for example, set upload an image with GL_SRGB format instead of GL_RGB but do glDisable( GL_FRAMEBUFFER_SRGB )?

@illwieckz illwieckz force-pushed the illwieckz/srgb-native branch 2 times, most recently from 86e853b to b2f3100 Compare July 7, 2025 06:19
@illwieckz
Copy link
Member Author

what is expected if I, for example, set upload an image with GL_SRGB format instead of GL_RGB but do glDisable( GL_FRAMEBUFFER_SRGB )?

The question is now likely irrelevant.

@illwieckz
Copy link
Member Author

illwieckz commented Jul 7, 2025

It now works with both maps built with and without the -sRGB q3map2 compiler option.

But you have to disable the tone mapper when running maps compiled with -sRGB, otherwise that looks very surreal.

I don't know anything about the tone mapper so I don't know if something is wrong.

Right now the camera post-process GLSL shader doesn't run in linear space because colorgrades were done for the non-linear space.

@illwieckz illwieckz force-pushed the illwieckz/srgb-native branch 2 times, most recently from 8702bec to b2a9fba Compare July 7, 2025 06:43
@illwieckz
Copy link
Member Author

The 2D rendering is done like before, as @slipher suggested:

We should probably stick with naive blending for the 2D rendering since that's what HTML/CSS do.
-- Unvanquished/Unvanquished#3390 (comment)

Actually it makes many things far easier, especially it doesn't require to know how the map should be rendered to render the UI, and it means the UI isn't affected by what's done there.

@slipher
Copy link
Member

slipher commented Jul 8, 2025

Wait, why would we even want GL_FRAMEBUFFER_SRGB? I don't think it can do anything useful for us. Apparently it is only useful for converting from colors linear to sRGB at a final stage of rendering, as described here. In principle, this is something we need to do at the point of the cameraEffects shader. But our current color grade and tonemap operations are designed for sRGB inputs. So it would work a lot more smoothly if we convert the colors from from linear space ourselves in cameraEffects before feeding them into color grades and tonemapping.

I wonder why GL_FRAMEBUFFER_SRGB would have any effect in the current version of the code though. Supposedly you have to create the framebuffer with an SRGB format for it to have an effect but the code does not appear to do that.

@illwieckz
Copy link
Member Author

illwieckz commented Jul 8, 2025

What I understood (but maybe I'm wrong), is that once GL_FRAMEBUFFER_SRGB is enabled, any subsequent framebuffer operation will assume any input and output is in sRGB and will convert them before and after processing (and also converting framebuffers back and forth when blending). I'm not saying this is truth, but I read in various places something that seemed to mean that, and it looks like doing things that way makes it work (I also read things that meant totally different things, but that seemed wrong).

Maybe we also need to set sRGB on framebuffers, maybe that's required for blending. I don't know, everyone is saying something different on the Internet.

@illwieckz
Copy link
Member Author

Also, something I've read (but I may be wrong) is that sRGB variants only exist for 8-bit formats, and some of our framebuffers are 16-bit… I don't know what to do with that information.

@illwieckz illwieckz force-pushed the illwieckz/srgb-native branch 2 times, most recently from 5383610 to 4e28980 Compare July 8, 2025 04:24
@slipher
Copy link
Member

slipher commented Jul 8, 2025

I found various people complaining of buggy handling of the framebuffer SRGB stuff. Like Nvidia applies it even when the framebuffer was not created as sRGB, or that Intel doesn't do it at all... another reason not to use it.

Some more random considerations:

  • Vertex colors of models are another thing that theoretically probably needs to be converted. Not sure if we actually have any models that use those.
  • Vertex colors of (3D) polygons too? OTOH we could just say that is the responsibility of the caller to use a linear space.
  • I guess the 2D vs. 3D shader registration flag stuff will become important now (since you only want sRGB-to-linear conversion when reading the latter) and probably uncover some bugs.

@illwieckz illwieckz force-pushed the illwieckz/srgb-native branch from 4e28980 to acceb04 Compare July 8, 2025 05:09
@illwieckz
Copy link
Member Author

Hmm, comparing a Xonotic map like afterslime on Dæmon and Darkplaces reveals there is still something wrong.

@illwieckz
Copy link
Member Author

We may face vertex lighting bugs unrelated to that branch, to begin with.

Or the function converting the color doesn't modify the input.

This is what is happening, Color::Color is const.

@illwieckz
Copy link
Member Author

With latest patch,

lightmap:

unvanquished_2025-07-25_132518_000

grid light:

unvanquished_2025-07-25_132538_000

vertex light:

unvanquished_2025-07-25_132607_000

station15:

unvanquished_2025-07-25_132857_000

vega:

unvanquished_2025-07-25_132918_000

Now the plants fit in their environment, and the computer does look dark because it is dark, not because of shadows.

@illwieckz illwieckz force-pushed the illwieckz/srgb-native branch from 043ac4b to af3e2f5 Compare July 25, 2025 19:46
@illwieckz
Copy link
Member Author

So, it looks like everything is now ready.

@illwieckz illwieckz force-pushed the illwieckz/srgb-native branch 4 times, most recently from 2a23a18 to 90d0fe8 Compare July 26, 2025 22:49
@illwieckz
Copy link
Member Author

So I believe all we had to care about is now taken care.

@illwieckz
Copy link
Member Author

We need a way to disable rim lighting when the linear pipeline is used. But we don't need to implement that to merge this branch. What we need is to implement this swithc before releasing.

@illwieckz
Copy link
Member Author

We need a way to disable rim lighting when the linear pipeline is used. But we don't need to implement that to merge this branch. What we need is to implement this swithc before releasing.

Well, it's only bad to mix linear pipeline + rim lighting + reflection mapping.

Copy link
Member

@slipher slipher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made some comments a couple days ago but apparently they didn't go through.

if ( ( backEnd.refdef.rdflags & ( RDF_NOWORLDMODEL | RDF_NOBLOOM ) )
|| !glConfig2.bloom || backEnd.viewParms.portalLevel > 0 ) {
|| !glConfig2.bloom || backEnd.viewParms.portalLevel > 0
|| !tr.worldLinearizeTexture )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I interpreted that preset disable bloom thing as you saying that it would ruin sRGB-aware maps, lol. Anyway if you think bloom looks fine in the linear space (I haven't tested), just get rid of this part. I like to use it as-is so the software should get out the way and let me choose my own settings.

enum
{
EXP_NONE,
EXP_NORM = BIT( 0 ),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this should be called EXP_CLAMP since that's what it does. It clamps, not normalizes.

@illwieckz illwieckz force-pushed the illwieckz/srgb-native branch 2 times, most recently from 6094f74 to 04a09fd Compare July 28, 2025 23:06
@illwieckz
Copy link
Member Author

I made some comments a couple days ago but apparently they didn't go through.

Now taken care of.

@slipher
Copy link
Member

slipher commented Jul 29, 2025

LGTM

Some non-blocking comments:

  • The atcshd fog is way too bright. But I'm not sure if that should be fixed engine-side or by changing parameters in the map.
  • Some dynamic lights are too dim, but we probably need to redo everything with dynamic lights anyway (Realtime light attenuation and colorspace #1703).
  • Grid lighting of models seems a bit too dim to me.

@slipher
Copy link
Member

slipher commented Jul 29, 2025

I believe this sentence in a commit message is outdated:

Video frame conversion is excluded from the scope of this commit,
it should be implemented later

@illwieckz illwieckz force-pushed the illwieckz/srgb-native branch from 04a09fd to 925128b Compare July 30, 2025 00:55
@illwieckz
Copy link
Member Author

I believe this sentence in a commit message is outdated:

Video frame conversion is excluded from the scope of this commit,
it should be implemented later

Ah yes, now fixed.

@illwieckz
Copy link
Member Author

The atcshd fog is way too bright. But I'm not sure if that should be fixed engine-side or by changing parameters in the map.

It's probably something similar to blended stuff. Taking care of a migration path for existing assets to the new pipeline would have to be taken care in future efforts.

@illwieckz
Copy link
Member Author

Many thanks to all who reviewed that in one way or another! ❤️

@illwieckz illwieckz merged commit 0b284f5 into master Aug 1, 2025
9 checks passed
@illwieckz illwieckz deleted the illwieckz/srgb-native branch August 1, 2025 09:56
@slipher slipher mentioned this pull request Aug 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants