egui_web: Vastly improve WebGL alpha blending

This finally fixes the rough edges on text, especially in light mode
This commit is contained in:
Emil Ernerfeldt 2021-06-04 23:03:48 +02:00
parent 2af86cd2c7
commit effd3c7440
3 changed files with 37 additions and 10 deletions

View file

@ -6,6 +6,7 @@ All notable changes to the `egui_web` integration will be noted in this file.
## Unreleased ## Unreleased
### Fixed ⭐ ### Fixed ⭐
* Improve alpha blending, making fonts look much better (especially in light mode)
* Fix double-paste bug * Fix double-paste bug

View file

@ -36,10 +36,23 @@ void main() {
/// Multiply vertex color with texture color (in linear space). /// Multiply vertex color with texture color (in linear space).
gl_FragColor = v_rgba * texture_rgba; gl_FragColor = v_rgba * texture_rgba;
// We must gamma-encode again since WebGL doesn't support linear blending in the framebuffer.
gl_FragColor = srgba_from_linear(v_rgba * texture_rgba) / 255.0;
// WebGL doesn't support linear blending in the framebuffer, // WebGL doesn't support linear blending in the framebuffer,
// so we apply this hack to at least get a bit closer to the desired blending: // so we do a hack here where we change the premultiplied alpha
gl_FragColor.a = pow(gl_FragColor.a, 1.6); // Empiric nonsense // to do the multiplication in gamma space instead:
// Unmultiply alpha:
if (gl_FragColor.a > 0.0) {
gl_FragColor.rgb /= gl_FragColor.a;
}
// Empiric tweak to make e.g. shadows look more like they should:
gl_FragColor.a *= sqrt(gl_FragColor.a);
// To gamma:
gl_FragColor = srgba_from_linear(gl_FragColor) / 255.0;
// Premultiply alpha, this time in gamma space:
if (gl_FragColor.a > 0.0) {
gl_FragColor.rgb *= gl_FragColor.a;
}
} }

View file

@ -23,10 +23,23 @@ void main() {
/// Multiply vertex color with texture color (in linear space). /// Multiply vertex color with texture color (in linear space).
gl_FragColor = v_rgba * texture_rgba; gl_FragColor = v_rgba * texture_rgba;
// We must gamma-encode again since WebGL doesn't support linear blending in the framebuffer.
gl_FragColor = srgba_from_linear(v_rgba * texture_rgba) / 255.0;
// WebGL doesn't support linear blending in the framebuffer, // WebGL doesn't support linear blending in the framebuffer,
// so we apply this hack to at least get a bit closer to the desired blending: // so we do a hack here where we change the premultiplied alpha
gl_FragColor.a = pow(gl_FragColor.a, 1.6); // Empiric nonsense // to do the multiplication in gamma space instead:
// Unmultiply alpha:
if (gl_FragColor.a > 0.0) {
gl_FragColor.rgb /= gl_FragColor.a;
}
// Empiric tweak to make e.g. shadows look more like they should:
gl_FragColor.a *= sqrt(gl_FragColor.a);
// To gamma:
gl_FragColor = srgba_from_linear(gl_FragColor) / 255.0;
// Premultiply alpha, this time in gamma space:
if (gl_FragColor.a > 0.0) {
gl_FragColor.rgb *= gl_FragColor.a;
}
} }