diff --git a/src/client/hud/layers/GraphicsSettingsModal.ts b/src/client/hud/layers/GraphicsSettingsModal.ts index d880e9515..39d12890b 100644 --- a/src/client/hud/layers/GraphicsSettingsModal.ts +++ b/src/client/hud/layers/GraphicsSettingsModal.ts @@ -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 ); } diff --git a/src/client/render/gl/RenderOverrides.ts b/src/client/render/gl/RenderOverrides.ts index 10eb57b68..44d51cdf7 100644 --- a/src/client/render/gl/RenderOverrides.ts +++ b/src/client/render/gl/RenderOverrides.ts @@ -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; diff --git a/src/client/render/gl/RenderSettings.ts b/src/client/render/gl/RenderSettings.ts index cca1cd316..9be2c64fb 100644 --- a/src/client/render/gl/RenderSettings.ts +++ b/src/client/render/gl/RenderSettings.ts @@ -191,6 +191,7 @@ export interface RenderSettings { structureLevel: { scale: number; outlineWidth: number; + offsetY: number; }; bar: { healthBarW: number; diff --git a/src/client/render/gl/debug/Layout.ts b/src/client/render/gl/debug/Layout.ts index 242b935f9..eefaaaa65 100644 --- a/src/client/render/gl/debug/Layout.ts +++ b/src/client/render/gl/debug/Layout.ts @@ -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"), diff --git a/src/client/render/gl/passes/StructureLevelPass.ts b/src/client/render/gl/passes/StructureLevelPass.ts index b20e41b95..0964181df 100644 --- a/src/client/render/gl/passes/StructureLevelPass.ts +++ b/src/client/render/gl/passes/StructureLevelPass.ts @@ -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); diff --git a/src/client/render/gl/render-settings.json b/src/client/render/gl/render-settings.json index 21a6c90be..b78bbb998 100644 --- a/src/client/render/gl/render-settings.json +++ b/src/client/render/gl/render-settings.json @@ -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, diff --git a/src/client/render/gl/shaders/structure-level/structure-level.vert.glsl b/src/client/render/gl/shaders/structure-level/structure-level.vert.glsl index 27ef723ca..ff528269b 100644 --- a/src/client/render/gl/shaders/structure-level/structure-level.vert.glsl +++ b/src/client/render/gl/shaders/structure-level/structure-level.vert.glsl @@ -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