Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve text redering and do all color operation in gamma space #2071

Merged
merged 15 commits into from Sep 24, 2022

Conversation

emilk
Copy link
Owner

@emilk emilk commented Sep 22, 2022

Closes #1410
Closes #1455
Closes #1411

Summary

This PR removes the linear framebuffer blending, and the linear blending in the pixel shader. Basically all color operations are now done in gamma space on the GPU. Only the sRGB-aware texture sampling is kept (when available).

Background

An early design decision in egui was to do all color operations in linear space. This is what makes sense physically, and is the standard for e.g. PBR. Gamma space is based on human perception and is non-physical. However, it turned out that getting proper anti-aliasing of fonts was very difficult to accomplish in linear space. This is not so strange when you think about it: you want to anti-alias using a perceptually linear gradient, not a physically linear.

Consequences

  • Better text in general, especially in low-contrast situations (gray on gray, white on white, …)
  • Better colored text (no more gray fringes)
  • Better anti-aliasing via feathering. A dark-on-bright line should now look the same width as a bright-on-dark line
  • Different window shadows
  • Image tinting will work differently

For integrations

  • Turn off linear (sRGB aware) framebuffer blending
  • Do all color operations in gamma-space in the shaders.

Here is the vertex shader you need:

void main() {
    gl_Position = vec4(
                      2.0 * a_pos.x / u_screen_size.x - 1.0,
                      1.0 - 2.0 * a_pos.y / u_screen_size.y,
                      0.0,
                      1.0);
    v_rgba_in_gamma = a_srgba / 255.0;
    v_tc = a_tc;
}

And here is the fragment shader:

// 0-1 sRGB gamma  from  0-1 linear
vec3 srgb_gamma_from_linear(vec3 rgb) {
    bvec3 cutoff = lessThan(rgb, vec3(0.0031308));
    vec3 lower = rgb * vec3(12.92);
    vec3 higher = vec3(1.055) * pow(rgb, vec3(1.0 / 2.4)) - vec3(0.055);
    return mix(higher, lower, vec3(cutoff));
}

// 0-1 sRGBA gamma  from  0-1 linear
vec4 srgba_gamma_from_linear(vec4 rgba) {
    return vec4(srgb_gamma_from_linear(rgba.rgb), rgba.a);
}

void main() {
#if SRGB_TEXTURES
    vec4 texture_in_gamma = srgba_gamma_from_linear(texture2D(u_sampler, v_tc));
#else
    vec4 texture_in_gamma = texture2D(u_sampler, v_tc);
#endif

    gl_FragColor = v_rgba_in_gamma * texture_in_gamma;
}

SRGB_TEXTURES indicates if you have an sRGB-aware texture sampler. It is recommended that you do.

Before

before-color-test

Notice the ugly artifacts when painting white text on white background. Also notice how the black text on white background is not really black, but gray.

After

after-color-test

Notice how the dark text on white background is now much darker and legible.
You can also notice that the text and the lines now look to have the same weight black-on-white as when white-on-black.

@emilk emilk marked this pull request as ready for review September 24, 2022 15:35
@emilk emilk merged commit 4ac1e28 into master Sep 24, 2022
@emilk emilk deleted the fix-text-blending branch September 24, 2022 15:53
emilk added a commit to rerun-io/rerun that referenced this pull request Sep 24, 2022
Includes recent improvements to text rendering:
* emilk/egui#2071
* emilk/egui#2070
* emilk/egui#2069
emilk added a commit to rerun-io/rerun that referenced this pull request Sep 24, 2022
Includes recent improvements to text rendering:
* emilk/egui#2071
* emilk/egui#2070
* emilk/egui#2069
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Font rendering with gray Rgba color is ugly Bright text is too faint/weak
1 participant