fix(style): tint the surface instead of repainting it
Both remaining complaints had one cause. The window paints its own background, and the backdrop was filling the same area a second time. Two stacked layers turn a translucent window solid, which is the density over the chat log. And an opaque fill has to carry the entire gradient by itself. That is where the banding came from: a shallow ramp across an opaque surface crosses so few 8-bit values that each one covers a visible stripe. Nothing sits underneath to break them up. So it tints now. Near-transparent white at the top, near-transparent black at the bottom, straight over whatever the window already drew. The window colour stays visible, the ramp only shades it, and the game showing through disperses what little stepping is left. The sidebar does the same with a flat black wash rather than a repainted darker surface. Motes are roughly half as bright everywhere, and the chat log takes 10% of that. DrawVerticalGradient stays for the segmented control, which paints a surface that genuinely is its own rather than one already drawn underneath.
This commit is contained in:
@@ -38,18 +38,14 @@ internal sealed class TabSidebar
|
||||
var min = ImGui.GetWindowPos();
|
||||
var max = min + ImGui.GetWindowSize();
|
||||
|
||||
var surface = ColourUtil.RgbaToAbgr(_resolver.Resolve(Token.SurfaceBase, colors));
|
||||
var accent = ColourUtil.RgbaToAbgr(_resolver.Resolve(Token.AccentPrimary, colors));
|
||||
|
||||
// Darker than the content pane so the two read as separate planes rather
|
||||
// than one wide surface with a line drawn down it.
|
||||
dl.DrawVerticalGradient(
|
||||
min,
|
||||
max,
|
||||
ColourUtil.LerpTowardBlack(surface, 0.25f),
|
||||
topLift: 0.10f,
|
||||
bottomDrop: 0.06f
|
||||
);
|
||||
// A wash of black rather than a repainted surface. The window has drawn
|
||||
// its own background already; filling over it stacks a second layer and
|
||||
// turns a translucent window solid. This only needs to read as the
|
||||
// darker of two planes, and a tint does that.
|
||||
var opacity = ((ImGui.GetColorU32(ImGuiCol.WindowBg) >> 24) & 0xFFu) / 255f;
|
||||
dl.AddRectFilled(min, max, (uint)(0x38 * opacity) << 24);
|
||||
|
||||
// The icon font has no ASCII glyphs, so anything textual drawn inside a
|
||||
// FontAwesome scope comes out blank -- twice bitten in this plugin. The
|
||||
|
||||
@@ -104,13 +104,13 @@ internal sealed class AmbientParticles
|
||||
dl.AddCircleFilled(
|
||||
pos,
|
||||
radius * 2.1f,
|
||||
ColourUtil.ApplyAlpha(accentAbgr, 0.13f * edge * pulse * intensity),
|
||||
ColourUtil.ApplyAlpha(accentAbgr, 0.075f * edge * pulse * intensity),
|
||||
10
|
||||
);
|
||||
dl.AddCircleFilled(
|
||||
pos,
|
||||
radius,
|
||||
ColourUtil.ApplyAlpha(accentAbgr, 0.42f * edge * pulse * intensity),
|
||||
ColourUtil.ApplyAlpha(accentAbgr, 0.20f * edge * pulse * intensity),
|
||||
10
|
||||
);
|
||||
}
|
||||
|
||||
@@ -35,37 +35,37 @@ internal sealed class SurfaceBackdrop
|
||||
var max = min + ImGui.GetWindowSize();
|
||||
var colors = _themes.Active.Colors;
|
||||
|
||||
// Opacity taken from the window's own background colour rather than
|
||||
// assumed. BgAlpha only reaches WindowBg, so a draw-list fill painted at
|
||||
// full opacity turns a deliberately translucent window into a solid
|
||||
// block -- which is exactly how the settings pane ended up looking like
|
||||
// a foreign object next to the chat window.
|
||||
var windowAlpha = ((ImGui.GetColorU32(ImGuiCol.WindowBg) >> 24) & 0xFFu) / 255f;
|
||||
// Modulation, not a second ground. The window has already painted its
|
||||
// own background; filling the same area again stacked two layers and
|
||||
// made a deliberately translucent window read as solid. Worse, an opaque
|
||||
// fill had to carry the whole gradient by itself, which is what produced
|
||||
// the banding -- a shallow ramp across an opaque surface crosses few
|
||||
// enough 8-bit values that each covers a visible stripe.
|
||||
//
|
||||
// Near-transparent white over black instead: the window colour stays
|
||||
// visible underneath, the ramp only tints it, and the game showing
|
||||
// through breaks up any step that is left.
|
||||
var opacity = ((ImGui.GetColorU32(ImGuiCol.WindowBg) >> 24) & 0xFFu) / 255f;
|
||||
var lift = 0x00FFFFFFu | ((uint)(0x0E * opacity) << 24);
|
||||
var drop = 0x00000000u | ((uint)(0x1A * opacity) << 24);
|
||||
dl.AddRectFilledMultiColor(min, max, lift, lift, drop, drop);
|
||||
|
||||
var surface = ColourUtil.RgbaToAbgr(_resolver.Resolve(Token.SurfaceBase, colors));
|
||||
if (darken > 0f)
|
||||
surface = ColourUtil.LerpTowardBlack(surface, darken);
|
||||
surface = ColourUtil.ApplyAlpha(surface, windowAlpha);
|
||||
dl.AddRectFilled(min, max, (uint)(0xFF * darken * opacity) << 24);
|
||||
|
||||
var accent = ColourUtil.RgbaToAbgr(_resolver.Resolve(Token.AccentPrimary, colors));
|
||||
|
||||
// Shallower than it was. The banding people see in a large gradient is
|
||||
// 8-bit quantisation: a gentle ramp crosses few enough values that each
|
||||
// one covers a visible band of pixels. Less range means fewer, fainter
|
||||
// steps, and the window's translucency breaks up what is left.
|
||||
dl.DrawVerticalGradient(min, max, surface, topLift: 0.10f, bottomDrop: 0.07f);
|
||||
|
||||
if (accentWashHeight > 0f)
|
||||
dl.AddRectFilledMultiColor(
|
||||
min,
|
||||
new Vector2(max.X, min.Y + (max.Y - min.Y) * accentWashHeight),
|
||||
ColourUtil.ApplyAlpha(accent, 0.09f * windowAlpha),
|
||||
ColourUtil.ApplyAlpha(accent, 0.045f * windowAlpha),
|
||||
ColourUtil.ApplyAlpha(accent, 0.07f * opacity),
|
||||
ColourUtil.ApplyAlpha(accent, 0.035f * opacity),
|
||||
accent & 0x00FFFFFFu,
|
||||
accent & 0x00FFFFFFu
|
||||
);
|
||||
|
||||
if (moteIntensity > 0f)
|
||||
_motes.Draw(dl, min, max, accent, moteIntensity * windowAlpha);
|
||||
_motes.Draw(dl, min, max, accent, moteIntensity * opacity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,7 +389,7 @@ internal sealed class MainWindow : Window, IFocusableChatWindow
|
||||
// a settings pane, which is read in glances; a chat log is read
|
||||
// line by line, and anything drifting behind the text competes
|
||||
// with it. What is left is barely a texture.
|
||||
_backdrop.Draw(accentWashHeight: 0f, moteIntensity: 0.18f);
|
||||
_backdrop.Draw(accentWashHeight: 0f, moteIntensity: 0.10f);
|
||||
|
||||
if (_activeTab is not null)
|
||||
_messages.Draw(_activeTab);
|
||||
|
||||
Reference in New Issue
Block a user