alacritty / alacritty/alacritty
Subpixel fonts aren't rendered correctly
- Lenguaje dominante
- Rust
- Estrellas
- 65.7k
- Forks
- 3.6k
- Merge medio
- 3 h 5 min
- PR fusionados (30 d)
- 3
Descripción
### System
OS: Windows
Version: alacritty 0.4.2 (f68de37)
Windows: ConPTY
### Logs
Font/Terminal size: 9 with bitstream vera sans mono
Hello! Alacritty doesn't handle rendering subpixel fonts correctly. I thought I'd document the issue in depth:
This is what an example from alacritty looks like:

This is sample text rendered in a different application that is rendered incorrectly, similar settings:

This is sample text correctly rendered with sRGB correct blending:

I had a brief look through the rendering pipeline, as far as I can tell the issue is here:
```
// Regular text glyphs.
vec3 textColor = texture(mask, TexCoords).rgb;
alphaMask = vec4(textColor, textColor.r);
color = vec4(fg, 1.0);
```
Combined with this piece of code:
```
let windowed_context =
create_gl_window(window_builder.clone(), &event_loop, false, vsync, size)
.or_else(|_| create_gl_window(window_builder, &event_loop, true, vsync, size))?;
```
This looks like it tries to create a window with sRGB disabled, followed by making one with sRGB enabled if that fails. Currently alacritty only renders text correctly with sRGB enabled, but there's no reason why both can't work
textColor here looks like alpha for subpixel fonts, which is good, although strictly speaking it is alpha, not colour. The blend equation is
```
gl::BlendFunc(gl::SRC1_COLOR, gl::ONE_MINUS_SRC1_COLOR);
```
Using dual source blending, where src1_color = alphaMask, here the linear subpixels
This gives the final result: Foreground_colour * subpixel_alpha3 + destination_colour * (1-subpixel_alpha3). The problem is, foreground colour and destination colour are both in sRGB for the blend equation when sRGB framebuffers are disabled, which makes this blending incorrect. Its pretty straightforward to convert foreground colour to linear colour if the render window doesn't have srgb enabled (although if you use pow(colour, 2.2) i'll complain very loudly, [see this](https://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html)), which makes destination colour the issue
One way to resolve this would be to render to an offscreen render target instead in linear colour, which is 4 component linear floats, then manually gamma correct afterwards when you blit back to the main render window. Or, you could create an offscreen sRGB enabled offscreen texture (which shouldn't run into to pixel format issues) and render to that before blitting. Or do both, conditionally depending on whether or not sRGB is available (unlikely to be an issue targeting desktop, but some linux drivers implement sRGB textures weirdly)
Decoupling the correctness of the text from the render window format is probably a good idea, given that it seems to have issues with getting the correct pixel formats from a look at the commit history. The issues here also apply to general colour rendering, and probably the emojis too, but I have skipped over all of that for simplicity
Thanks!
Guía de contribución
Evaluación
Este issue todavía no se ha evaluado.