wez / wezterm

A GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust
https://wezfurlong.org/wezterm/
Other
17.84k stars 799 forks source link

colors behind the window bleed through into text color #470

Closed wez closed 3 years ago

wez commented 3 years ago

I'll just hijack this issue, as my issue seems to be caused by the fix for this one – if I should open a separate issue instead, I'd happily oblige, of course!

Basically I have artifacts looking quite related only with all versions of wezterm with the fix from 70a364eb3fd5624d950f6ed87a239f97b00c6028 applied. To pinpoint it, I have build a version from 70a364eb3fd5624d950f6ed87a239f97b00c6028 as well as one from the parent commit (dafb429da0645bba6499b338f8c15f0a10619a1d).

My environment is: Linux Wayland with sway (Arch), but it also seems to happen for a colleague on X11 as well.

Things I have already tried: Using a different font, different font_antialias or font_hinting settings, enabling/disabling wayland, disabling bold_brightens_ansi_colors, removing allow_square_glyphs_to_overflow_width = 'Always', trying the different freetype_interpreter_version options and disabling my colors altogether.

It also does happen inside as well as outside of tmux.

Interestingly, those artifacts only begin to become really obvious towards the center of the screen.

To show the kind of artifacts that appear, here are two screenshots with the printf "\e[46m\e[30m[foo\e[0m\e[46m\e[31mbar]\e[0m" command from above run in different places with the two versions:

Using a build from dafb429da0645bba6499b338f8c15f0a10619a1d

image

Using a build from 70a364eb3fd5624d950f6ed87a239f97b00c6028

image

My unmodified (as in: without the attempts to mitigate it, as described above) wezterm.lua is:

local wezterm = require 'wezterm';
function font_with_fallback(name, params)
  local names = {name, "Hack NF JBM Ligatured", "JetBrains Mono", "Noto Color Emoji"}
  return wezterm.font_with_fallback(names, params)
end
return {
  font_size = 12.0,
  font_antialias = "Subpixel", -- None, Greyscale, Subpixel
  font_hinting = "Full",  -- None, Vertical, VerticalSubpixel, Full
  bold_brightens_ansi_colors = true,
  scrollback_lines = 10000,
  enable_wayland = true,
  font = font_with_fallback("Hack JBM Ligatured"),
  allow_square_glyphs_to_overflow_width = 'Always',
  colors = {
      foreground = "#7E8792",
      background = "#262626",
      cursor_bg = "#55606d",
      cursor_fg = "#262626",
      cursor_border = "#55606d",
      selection_bg = "#55606d",
      selection_fg = "#262626",
      ansi = {"#262626", "#5B738F", "#76efc7", "#df7c7c", "#3bba90", "#91c1f8", "#4d5653", "#55606d"},
      brights = {"#454545", "#4E8A76", "#6194CD", "#ef9999", "#404040", "#3D4349", "#56fbc4", "#3D4349"},
      tab_bar = {
        background = "#404040",
        active_tab = {
          bg_color = "#4E8A76",
          fg_color = "#262626",
        },
        inactive_tab = {
          bg_color = "#6e88a6",
          fg_color = "#262626",
        },
      },
  },
}

Originally posted by @evs-ch in https://github.com/wez/wezterm/issues/413#issuecomment-775895879

wez commented 3 years ago

It's weird that this is basically opposite of the behavior in #413, or rather, I find it puzzling because you mentioned that it also happens for a colleague under X11. It would make sense that the wayland related workaround that is worked around in 413 might cause problems for wayland, but not for X11 too.

evs-ch commented 3 years ago

Thanks for picking this up :)

Wayland:

 2021-02-10T11:13:02.676Z INFO  wezterm_mux_server_impl::local > setting up /run/user/1000/wezterm/gui-sock-3498446
 2021-02-10T11:13:03.223Z INFO  wezterm_gui::gui::termwindow   > OpenGL initialized! Mesa Intel(R) HD Graphics 530 (SKL GT2) OpenGL ES 3.2 Mesa 20.3.4 is_context_loss_possible=false wezterm version: 20201101-103216-403d002d-308-gdafb429d

With enable_wayland = false (I assume that (and having XWayland available) should be enough to use XWayland?):

 2021-02-10T11:13:56.661Z INFO  wezterm_mux_server_impl::local > setting up /run/user/1000/wezterm/gui-sock-3501119
 2021-02-10T11:13:57.386Z INFO  wezterm_gui::gui::termwindow   > OpenGL initialized! Mesa Intel(R) HD Graphics 530 (SKL GT2) OpenGL ES 3.2 Mesa 20.3.4 is_context_loss_possible=false wezterm version: 20201101-103216-403d002d-308-gdafb429d

Wayland, version that's working:

 2021-02-10T11:11:48.057Z INFO  wezterm_mux_server_impl::local > setting up /run/user/1000/wezterm/gui-sock-3494430
 2021-02-10T11:11:48.543Z INFO  wezterm_gui::gui::termwindow   > OpenGL initialized! Mesa Intel(R) HD Graphics 530 (SKL GT2) OpenGL ES 3.2 Mesa 20.3.4 is_context_loss_possible=false wezterm version: 20201101-103216-403d002d-308-gdafb429d

I also get a lot of ERROR wezterm_term::terminalstate > unhandled TerminalMode 34 lines with old and new versions, but those do not seem to cause any observable issues and seem unrelated to the issue.

Haven't gotten the log line from the colleague yet, will add it once I have it.

wez commented 3 years ago

Well, for another weird data point, I saw some shine-through from an orange banner behind my terminal text on a system running mutter + x11. It's extra weird because transparency/opacity doesn't work there, and that system doesn't have transparency enabled either. I'll look at this some more over the weekend!

bew commented 3 years ago

Note, on windows I saw these kind of artifacts also. Changing font_antialiasing option didn't help.

evs-ch commented 3 years ago

That (transparency/shine-through) might actually be part of what's happening on my end as well. I do have a wallpaper set (which is almost never visible, so I wouldn't even have thought of this being in any way related), which, incidentally, has a lighter area pretty much in the region where the artifacts appear to be worst.

(more or less a slight variation of this: https://dorksideoftheforce.com/files/2020/02/themandalorian-thechild-2_a75295e2.jpeg :)

tilacog commented 3 years ago

This issue also affects me on Gnome at Arch Linux when running wezterm version 20210203-095643-70a364eb-24-g005b492a.

Its like I can "see through" the characters outline. Depending of what window/picture is behind. This issue affects more the center of the display than the borders.

wez commented 3 years ago

This is a headache for sure!

I pushed a commit that I think is somewhere between the before and after #413.

My test config for this is to set the window opacity to 0.7 and then put a chrome window with the google search page (all white) behind wezterm. The opacity isn't required to trigger the issue, but helps to see where the shine-through is happening.

In this screenshot the upper window is from before the changes in 0473e1de running under mutter in wayland mode with the nouveau driver, and the lower window is from after that change:

image

From that, it's clear that the white window is saturating the colors in wezterm. I believe the cause is that the resultant alpha channel value after rendering the text isn't close to 1.0 (because it's been blended with the black background color and its lower alpha, pulling the alpha value down). That lower value weights the white of the occluded window higher and produces the unwanted saturation effect.

What I really want is for the result of compositing the glyphs to have alpha=1.0 but there doesn't appear to be a way to express that in opengl.

The approach in the commit I just pushed is to add the background and glyph alpha values and hope that it is ~1.0.

I think this resolves #470 in the sense that #413 regressed this behavior, but I'm not sure if @dmfay is satisfied!

evs-ch commented 3 years ago

That certainly sounds like a headache – I'd love to give any kind of more meaningful aid, but I have absolutely no experience with OpenGL programming at all.

Still, at least I can report: things now look fine again on my system with a fresh build from the latest commit :)

hgkamath commented 3 years ago

I think I ran into this.

There is some translucency by default when wezterm starts. https://wezfurlong.org/wezterm/config/appearance.html?highlight=opacity#window-background-opacity

return {
  window_background_opacity = 1.0,
  text_background_opacity = 1.0,
}

Furthermore, the translucency did not disappear on configuration write-auto-reload. I had to kill-restart wezterm for the translucency to go away. I still wonder if there is still residual transparency and font-antialiasing problems, as rendering in my virtualbox/llvmpipe is not as good as windows-native. Though I cannot be sure of it.

dmfay commented 3 years ago

I regret to report the rabbit hole goes deeper -- on main I've got darker pixels on the border of bar again:

wezterm-main

red: #9c6b80 (luminance 52) cyan: #6698aa (luminance 53) on the border: #736475 (luminance 43)

70a364eb -- which, on zooming kind of ludicrously far in, actually still has faint bordering, to the tune of #806C80 (luminance 46):

wezterm-70a364eb

and termite for comparison, which doesn't let me zoom in as far. It doesn't seem to be doing alpha blending in the same way at all -- the glyph edges are red with lower and lower alpha, as opposed to gray.

wezterm-termite

I checked out the glium docs and tried a bunch of variations on blend_but_set_alpha_to_one. I couldn't figure out a way to colorize the blend à la termite, and nothing I tried looked better than glium::Blend::alpha_blending() as in 70a364eb (i.e. all additive, alpha source factor SourceAlpha, destination OneMinusSourceAlpha).

However, someone's in the glium issues asking whether that calculation is correct. I applied his version (alpha source factor One, destination OneMinusSourceAlpha) but it seems basically comparable to main.

wez commented 3 years ago

@dmfay Thanks for the tip on the bad alpha blending math! I've switched to the conrod implementation. Even with that, there were still dark fringes visible around the glyphs.

I've pushed a different bit of code in the shader to colorize the glyphs; the new technique works by converting the color to HSV and then multiplying the V by the alpha. Operating in HSV compensates for perceived intensity differences in the R, G and B channels.

Since this math ignores the RGB components from the glyph rasterization and takes only the A value, this is theoretically "wrong" when font_antialias=Subpixel. I've included a colorize function in the shader that factors in the RGB values and that should theoretically be "right" for Subpixel, but I don't think it looks as good--it has more pronounced darker fringes. It may be possible to compensate for that by scaling the R, G and B values by constants to compensate for the perceived intensity... I just don't fancy figuring that out right at this moment.

Here's a screenshot contrasting before and after this change on my mac:

Screen Shot 2021-02-15 at 21 34 22

Left: 1c85950f, Right: 145b7695c7b873b008d2d911f236318604f379f1

dmfay commented 3 years ago

I think we have a winner!

1613484643

github-actions[bot] commented 1 year ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.