Tune structure rendering to match the previous version's look

Bring the WebGL structure renderer closer to the old canvas render:
larger icons, classic icon styling by default, and more prominent,
better-positioned level numbers.
This commit is contained in:
evanpelle
2026-06-13 09:28:47 -07:00
parent de84f0e867
commit 49a12519d7
7 changed files with 53 additions and 8 deletions
@@ -320,7 +320,7 @@ export class GraphicsSettingsModal extends LitElement implements Controller {
private currentClassicIcons(): boolean {
return (
this.userSettings.graphicsOverrides().structure?.classicIcons ?? false
this.userSettings.graphicsOverrides().structure?.classicIcons ?? true
);
}
+2 -2
View File
@@ -27,8 +27,8 @@ export function applyGraphicsOverrides(
if (overrides.name?.hoverGlowAlpha !== undefined) {
settings.name.hoverGlowAlpha = overrides.name.hoverGlowAlpha;
}
if (overrides.structure?.classicIcons === true) {
// Classic look: lighter player-colored shape behind a darkened
if (overrides.structure?.classicIcons ?? true) {
// Classic look (default): lighter player-colored shape behind a darkened
// player-colored icon glyph (matching the old canvas renderer's
// structureColors().dark), with a touch of translucency.
settings.structure.borderDarken = 0.7;
+1
View File
@@ -191,6 +191,7 @@ export interface RenderSettings {
structureLevel: {
scale: number;
outlineWidth: number;
offsetY: number;
};
bar: {
healthBarW: number;
+31 -1
View File
@@ -214,7 +214,7 @@ export function buildTree(s: RenderSettings, d: RenderSettings): DebugNode[] {
]),
folder("Structure", [
slider(s.structure, "iconSize", d.structure, 10, 60, 1),
slider(s.structure, "iconSize", d.structure, 10, 100, 1),
slider(s.structure, "dotsZoomThreshold", d.structure, 0.1, 2, 0.05),
slider(
s.structure,
@@ -269,6 +269,36 @@ export function buildTree(s: RenderSettings, d: RenderSettings): DebugNode[] {
),
]),
folder("Structure Level", [
slider(
s.structureLevel,
"scale",
d.structureLevel,
0.5,
3,
0.05,
"Scale",
),
slider(
s.structureLevel,
"outlineWidth",
d.structureLevel,
0,
20,
0.1,
"Outline Width (px)",
),
slider(
s.structureLevel,
"offsetY",
d.structureLevel,
-2,
2,
0.05,
"Height Above Icon",
),
]),
folder("Bar", [
slider(s.bar, "healthBarW", d.bar, 3, 30, 1, "Health Width"),
slider(s.bar, "healthBarH", d.bar, 1, 10, 1, "Health Height"),
@@ -65,9 +65,11 @@ export class StructureLevelPass {
private uIconSize: WebGLUniformLocation;
private uDotsThreshold: WebGLUniformLocation;
private uScaleFactor: WebGLUniformLocation;
private uIconGrowZoom: WebGLUniformLocation;
private uDistRange: WebGLUniformLocation;
private uOutlineWidth: WebGLUniformLocation;
private uLevelScale: WebGLUniformLocation;
private uLevelOffsetY: WebGLUniformLocation;
private uHighlightMask: WebGLUniformLocation;
private uHighlightDimAlpha: WebGLUniformLocation;
@@ -152,9 +154,11 @@ export class StructureLevelPass {
"uDotsThreshold",
)!;
this.uScaleFactor = gl.getUniformLocation(this.program, "uScaleFactor")!;
this.uIconGrowZoom = gl.getUniformLocation(this.program, "uIconGrowZoom")!;
this.uDistRange = gl.getUniformLocation(this.program, "uDistRange")!;
this.uOutlineWidth = gl.getUniformLocation(this.program, "uOutlineWidth")!;
this.uLevelScale = gl.getUniformLocation(this.program, "uLevelScale")!;
this.uLevelOffsetY = gl.getUniformLocation(this.program, "uLevelOffsetY")!;
this.uHighlightMask = gl.getUniformLocation(
this.program,
"uHighlightMask",
@@ -290,9 +294,11 @@ export class StructureLevelPass {
gl.uniform1f(this.uIconSize, ss.iconSize);
gl.uniform1f(this.uDotsThreshold, ss.dotsZoomThreshold);
gl.uniform1f(this.uScaleFactor, ss.iconScaleFactorZoomedOut);
gl.uniform1f(this.uIconGrowZoom, ss.iconGrowZoom);
gl.uniform1f(this.uDistRange, this.distanceRange);
gl.uniform1f(this.uOutlineWidth, sl.outlineWidth);
gl.uniform1f(this.uLevelScale, sl.scale);
gl.uniform1f(this.uLevelOffsetY, sl.offsetY);
gl.uniform1i(this.uHighlightMask, this.highlightMask);
gl.uniform1f(this.uHighlightDimAlpha, ss.highlightDimAlpha);
+4 -3
View File
@@ -111,7 +111,7 @@
"railThickness": 1
},
"structure": {
"iconSize": 50,
"iconSize": 60,
"dotsZoomThreshold": 1.2,
"dotScale": 0.3,
"iconScaleFactorZoomedOut": 3,
@@ -153,8 +153,9 @@
"iconDarken": 0
},
"structureLevel": {
"scale": 1.2,
"outlineWidth": 1.4
"scale": 1,
"outlineWidth": 8,
"offsetY": -0.4
},
"bar": {
"healthBarW": 11,
@@ -16,12 +16,14 @@ uniform float uZoom;
uniform float uIconSize;
uniform float uDotsThreshold;
uniform float uScaleFactor;
uniform float uIconGrowZoom;
// Text sizing
uniform float uFontSize;
uniform float uAtlasScaleH;
uniform float uBase;
uniform float uLevelScale;
uniform float uLevelOffsetY; // extra height above icon, in halfIconSize units
out vec2 vUV;
flat out float vAlive;
@@ -37,6 +39,9 @@ void main() {
float iconScale;
if (uZoom <= uDotsThreshold) {
iconScale = 0.0; // hidden in dots mode
} else if (uZoom >= uIconGrowZoom) {
// World-anchored: grow with the map past this zoom, matching the icons.
iconScale = uZoom / uIconGrowZoom;
} else {
iconScale = min(1.0, uZoom / uScaleFactor);
}
@@ -78,7 +83,9 @@ void main() {
// Position above icon center
vec2 center = vec2(worldX + 0.5, worldY + 0.5);
float baselineY = -uBase * 0.5;
float yOff = -halfIconSize - levelScale * uBase * 0.6; // above icon top edge
// above icon top edge; uLevelOffsetY raises (or lowers) it proportionally
float yOff =
-halfIconSize * (1.0 + uLevelOffsetY) - levelScale * uBase * 0.6;
vec2 glyphOrigin = vec2(
cursorX + m0.y, // + xoffset