Make Glimmer Look Beautiful (#4130)

* about to break this all

* event goidacode

* cleanup

* cleanup 2

* cleanup 3

* cleanup 4

is it even worth bothering with these descriptions. added newline to end of a couple files

* single extra space WAUGH

* toggleable + minor cleanup

* that was reverted already what

why did merge conflict editor add in a line that isn't even present on master?? huh???

* fixops

GlimmerSystem looks like That to avoid extraneous network events being raised if something is attempting to push glimmer over 1000
This commit is contained in:
KOTOB 2025-08-19 20:54:19 -07:00 committed by GitHub
parent b01aba8348
commit bfa721ea53
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 218 additions and 1 deletions

View File

@ -14,6 +14,7 @@
FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="DisableFiltersCheckBox" Text="{Loc 'ui-options-no-filters'}" />
<CheckBox Name="DisableGlimmerEffectCheckBox" Text="{Loc 'ui-options-disable-glimmer-effect'}" />
<CheckBox Name="AutoFillHighlightsCheckBox" Text="{Loc 'ui-options-auto-fill-highlights'}" />
<dvui:OptionColorSlider Name="HighlightsColorSlider"
Title="{Loc 'ui-options-highlights-color'}"

View File

@ -14,6 +14,7 @@ public sealed partial class DeltaTab : Control
IoCManager.InjectDependencies(this);
Control.AddOptionCheckBox(DCCVars.NoVisionFilters, DisableFiltersCheckBox);
Control.AddOptionCheckBox(DCCVars.DisableGlimmerShader, DisableGlimmerEffectCheckBox);
Control.AddOptionCheckBox(DCCVars.ChatAutoFillHighlights, AutoFillHighlightsCheckBox);
Control.AddOptionColorSlider(DCCVars.ChatHighlightsColor, HighlightsColorSlider);

View File

@ -0,0 +1,66 @@
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Client._DV.Overlays;
public sealed class GlimmerOverlay : Overlay
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly IPlayerManager _player = default!;
public override OverlaySpace Space => OverlaySpace.WorldSpace;
private readonly ShaderInstance _glimmerShader;
private readonly ProtoId<ShaderPrototype> _shaderProto = "HighGlimmer";
private float _visualGlimmerLevel = 0f;
public int ActualGlimmerLevel = 0;
public GlimmerOverlay()
{
IoCManager.InjectDependencies(this);
_glimmerShader = _prototype.Index(_shaderProto).Instance().Duplicate();
}
protected override bool BeforeDraw(in OverlayDrawArgs args)
{
if (_player.LocalEntity == null)
{
return false;
}
return base.BeforeDraw(in args);
}
protected override void Draw(in OverlayDrawArgs args)
{
var lastFrameTime = (float) _timing.FrameTime.TotalSeconds;
// lerp glimmer level to avoid jumps
_visualGlimmerLevel = !MathHelper.CloseTo(_visualGlimmerLevel, ActualGlimmerLevel, 0.001f)
? float.Lerp(_visualGlimmerLevel, ActualGlimmerLevel, 0.1f * lastFrameTime)
: ActualGlimmerLevel;
// clamp glimmer to 0-1, map to exponential ease-out
var progress = Math.Clamp((_visualGlimmerLevel - 700f) / 300f,0,1);
var size = 1f - MathF.Pow(2f, -8f * progress);
_glimmerShader.SetParameter("size",size);
var worldHandle = args.WorldHandle;
var viewport = args.WorldBounds;
worldHandle.UseShader(_glimmerShader);
worldHandle.DrawRect(viewport, Color.White);
worldHandle.UseShader(null);
}
// used to avoid lerp jump if overlay was removed weirdly prior
public void Reset()
{
_visualGlimmerLevel = ActualGlimmerLevel;
}
}

View File

@ -0,0 +1,64 @@
using Content.Shared._DV.CCVars;
using Content.Shared.Psionics.Glimmer;
using Robust.Client.Graphics;
using Robust.Shared.Configuration;
namespace Content.Client._DV.Overlays;
public sealed partial class GlimmerOverlaySystem : EntitySystem
{
[Dependency] private readonly IOverlayManager _overlayMan = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
private GlimmerOverlay _overlay = default!;
private bool _cvarDisabled;
public override void Initialize()
{
base.Initialize();
_overlay = new GlimmerOverlay();
SubscribeNetworkEvent<GlimmerChangedEvent>(OnGlimmerChanged);
_cfg.OnValueChanged(DCCVars.DisableGlimmerShader, OnDisableGlimmerShaderChanged);
}
private void OnGlimmerChanged(GlimmerChangedEvent eventArgs)
{
if(_cvarDisabled)
return;
if(eventArgs.Glimmer > 700)
{
_overlay.ActualGlimmerLevel = eventArgs.Glimmer;
if (!_overlayMan.HasOverlay<GlimmerOverlay>())
{
_overlay.Reset();
_overlayMan.AddOverlay(_overlay);
}
}
else
{
if (_overlayMan.HasOverlay<GlimmerOverlay>())
{
_overlayMan.RemoveOverlay(_overlay);
}
}
}
public override void Shutdown()
{
base.Shutdown();
_overlayMan.RemoveOverlay<GlimmerOverlay>();
}
private void OnDisableGlimmerShaderChanged(bool enabled)
{
_cvarDisabled = enabled;
if (enabled)
_overlayMan.RemoveOverlay(_overlay);
else if (_overlay.ActualGlimmerLevel > 700)
_overlayMan.AddOverlay(_overlay);
}
}

View File

@ -15,7 +15,15 @@ namespace Content.Shared.Psionics.Glimmer
public int Glimmer
{
get { return _glimmer; }
set { _glimmer = _enabled ? Math.Clamp(value, 0, 1000) : 0; }
set
{
var newGlimmer = _enabled ? Math.Clamp(value, 0, 1000) : 0;
if (_glimmer == newGlimmer)
return;
_glimmer = newGlimmer;
RaiseNetworkEvent(new GlimmerChangedEvent(_glimmer));
}
}
private bool _enabled;
public override void Initialize()
@ -62,4 +70,15 @@ namespace Content.Shared.Psionics.Glimmer
Dangerous,
Critical,
}
[Serializable, NetSerializable]
public sealed class GlimmerChangedEvent : EntityEventArgs
{
public int Glimmer { get; }
public GlimmerChangedEvent(int glimmer)
{
Glimmer = glimmer;
}
}
}

View File

@ -94,6 +94,12 @@ public sealed partial class DCCVars
public static readonly CVarDef<bool> NoVisionFilters =
CVarDef.Create("accessibility.no_vision_filters", true, CVar.CLIENTONLY | CVar.ARCHIVE);
/// <summary>
/// Disables the fullscreen shader at 700+ glimmer.
/// </summary>
public static readonly CVarDef<bool> DisableGlimmerShader =
CVarDef.Create("accessibility.disable_glimmer_shader", false, CVar.CLIENTONLY | CVar.ARCHIVE);
/// <summary>
/// Whether the Shipyard is enabled.
/// </summary>

View File

@ -0,0 +1,6 @@
using Robust.Shared.GameStates;
namespace Content.Shared._DV.Overlays;
[RegisterComponent, NetworkedComponent]
public sealed partial class GlimmerOverlayComponent : Component;

View File

@ -2,6 +2,7 @@ ui-options-tab-deltav = DeltaV
ui-options-general-forknotice = Note: These settings are fork-specific and might not apply on other servers.
ui-options-no-filters = Disable species vision filters
ui-options-disable-glimmer-effect = Disable high glimmer shader effect
## DeltaV NanoChat keybinds
ui-options-header-nano-chat = NanoChat

View File

@ -0,0 +1,4 @@
- type: shader
id: HighGlimmer
kind: source
path: "/Textures/_DV/Shaders/highglimmer.swsl"

View File

@ -0,0 +1,49 @@
// Shader by Xor, taken and modified from https://www.shadertoy.com/view/3fKSzc.
// Licensed under CC BY-NC-SA 3.0: https://creativecommons.org/licenses/by-nc-sa/3.0/deed.en
const highp float TimeScale = 0.2;
uniform highp float size = 1;
void fragment() {
vec2 iResolution = vec2(1.0);
vec2 I = UV * iResolution;
//Raymarch depth
float z = 0.0;
//Step distance
float d = 0.0;
//Raymarch iterator
float i = 0.0;
//Animation time
float t = TIME * TimeScale;
vec4 O = vec4(0.0);
//Clear fragColor and raymarch (some amount of) steps
while (i++ < 25) {
// sample point (from ray direction)
vec3 p = z * normalize(vec3(I + I, 0.0) - iResolution.xyx) + 0.1;
// polar coordinates
p = vec3(atan(p.y, p.x) * 2.0, p.z / (3.0*(3.0-size)), length(p.xy) - 4.5 - z * (0.5 * 2.8-size));
// apply turbulence
d = 0.0;
float j = 0.0;
while (++j < 9.0)
p += sin(p.yzx * j - t + 0.2 * i) / j;
// distance to cylinder and waves
d = 0.2 * length(vec4(p.z, 0.1 * cos(p * 3.0) - 0.1));
z += d;
// coloring and brightness
O += (1.0 + cos(i * 0.7 + vec4(6.0, 1.0, 2.0, 0.0))) / d / i;
}
// tanh tonemap
O = tanh(O * O / 900.0);
COLOR = O;
}