improve noir glasses shader (#37996)
* improve noir glasses shader * tweak values
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
@@ -7,9 +6,7 @@ namespace Content.Client.Overlays;
|
||||
|
||||
public sealed partial class BlackAndWhiteOverlay : Overlay
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
||||
public override bool RequestScreenTexture => true;
|
||||
@@ -22,17 +19,6 @@ public sealed partial class BlackAndWhiteOverlay : Overlay
|
||||
ZIndex = 10; // draw this over the DamageOverlay, RainbowOverlay etc.
|
||||
}
|
||||
|
||||
protected override bool BeforeDraw(in OverlayDrawArgs args)
|
||||
{
|
||||
if (!_entityManager.TryGetComponent(_playerManager.LocalEntity, out EyeComponent? eyeComp))
|
||||
return false;
|
||||
|
||||
if (args.Viewport.Eye != eyeComp.Eye)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void Draw(in OverlayDrawArgs args)
|
||||
{
|
||||
if (ScreenTexture == null)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Content.Shared.Inventory.Events;
|
||||
using Content.Shared.Overlays;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
|
||||
namespace Content.Client.Overlays;
|
||||
|
||||
|
||||
33
Content.Client/Overlays/NoirOverlay.cs
Normal file
33
Content.Client/Overlays/NoirOverlay.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Overlays;
|
||||
|
||||
public sealed partial class NoirOverlay : Overlay
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
||||
public override bool RequestScreenTexture => true;
|
||||
private readonly ShaderInstance _noirShader;
|
||||
|
||||
public NoirOverlay()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
_noirShader = _prototypeManager.Index<ShaderPrototype>("Noir").InstanceUnique();
|
||||
ZIndex = 9; // draw this over the DamageOverlay, RainbowOverlay etc, but before the black and white shader
|
||||
}
|
||||
|
||||
protected override void Draw(in OverlayDrawArgs args)
|
||||
{
|
||||
if (ScreenTexture == null)
|
||||
return;
|
||||
|
||||
var handle = args.WorldHandle;
|
||||
_noirShader.SetParameter("SCREEN_TEXTURE", ScreenTexture);
|
||||
handle.UseShader(_noirShader);
|
||||
handle.DrawRect(args.WorldBounds, Color.White);
|
||||
handle.UseShader(null);
|
||||
}
|
||||
}
|
||||
33
Content.Client/Overlays/NoirOverlaySystem.cs
Normal file
33
Content.Client/Overlays/NoirOverlaySystem.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Content.Shared.Inventory.Events;
|
||||
using Content.Shared.Overlays;
|
||||
using Robust.Client.Graphics;
|
||||
|
||||
namespace Content.Client.Overlays;
|
||||
|
||||
public sealed partial class NoirOverlaySystem : EquipmentHudSystem<NoirOverlayComponent>
|
||||
{
|
||||
[Dependency] private readonly IOverlayManager _overlayMan = default!;
|
||||
|
||||
private NoirOverlay _overlay = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
_overlay = new();
|
||||
}
|
||||
|
||||
protected override void UpdateInternal(RefreshEquipmentHudEvent<NoirOverlayComponent> component)
|
||||
{
|
||||
base.UpdateInternal(component);
|
||||
|
||||
_overlayMan.AddOverlay(_overlay);
|
||||
}
|
||||
|
||||
protected override void DeactivateInternal()
|
||||
{
|
||||
base.DeactivateInternal();
|
||||
|
||||
_overlayMan.RemoveOverlay(_overlay);
|
||||
}
|
||||
}
|
||||
@@ -85,6 +85,7 @@ public partial class InventorySystem
|
||||
SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<ShowSyndicateIconsComponent>>(RefRelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<ShowCriminalRecordIconsComponent>>(RefRelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<BlackAndWhiteOverlayComponent>>(RefRelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<NoirOverlayComponent>>(RefRelayInventoryEvent);
|
||||
|
||||
SubscribeLocalEvent<InventoryComponent, GetVerbsEvent<EquipmentVerb>>(OnGetEquipmentVerbs);
|
||||
SubscribeLocalEvent<InventoryComponent, GetVerbsEvent<InnateVerb>>(OnGetInnateVerbs);
|
||||
|
||||
10
Content.Shared/Overlays/NoirOverlayComponent.cs
Normal file
10
Content.Shared/Overlays/NoirOverlayComponent.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Overlays;
|
||||
|
||||
/// <summary>
|
||||
/// Makes the entity see everything with a sin city shader (everything in black and white, except red) by adding an overlay.
|
||||
/// When added to a clothing item it will also grant the wearer the same overlay.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class NoirOverlayComponent : Component;
|
||||
@@ -281,7 +281,7 @@
|
||||
- type: FlashImmunity
|
||||
- type: EyeProtection
|
||||
protectionTime: 5
|
||||
- type: BlackAndWhiteOverlay
|
||||
- type: NoirOverlay
|
||||
- type: Tag
|
||||
tags:
|
||||
- HamsterWearable
|
||||
|
||||
@@ -47,6 +47,12 @@
|
||||
kind: source
|
||||
path: "/Textures/Shaders/rainbow.swsl"
|
||||
|
||||
# sin city effect: everything is greyscale, except red
|
||||
- type: shader
|
||||
id: Noir
|
||||
kind: source
|
||||
path: "/Textures/Shaders/noir.swsl"
|
||||
|
||||
- type: shader
|
||||
id: CameraStatic
|
||||
kind: source
|
||||
@@ -108,4 +114,4 @@
|
||||
- type: shader
|
||||
id: Hologram
|
||||
kind: source
|
||||
path: "/Textures/Shaders/hologram.swsl"
|
||||
path: "/Textures/Shaders/hologram.swsl"
|
||||
|
||||
46
Resources/Textures/Shaders/noir.swsl
Normal file
46
Resources/Textures/Shaders/noir.swsl
Normal file
@@ -0,0 +1,46 @@
|
||||
// Sin City style shader.
|
||||
// Makes everything black and white, but keeps red colors.
|
||||
|
||||
uniform sampler2D SCREEN_TEXTURE;
|
||||
// Sensitivity, in degrees.
|
||||
const highp float RedHueRange = 5;
|
||||
const highp float MinSaturation = 0.4;
|
||||
|
||||
// https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB
|
||||
highp vec3 rgb2hsv(highp vec3 c) {
|
||||
highp float xMax = max(c.r, max(c.g, c.b));
|
||||
highp float xMin = min(c.r, min(c.g, c.b));
|
||||
highp float delta = xMax - xMin;
|
||||
|
||||
highp float hue = 0.0;
|
||||
if (delta > 0.0) {
|
||||
if (xMax == c.r) {
|
||||
hue = mod((c.g - c.b) / delta, 6.0);
|
||||
} else if (xMax == c.g) {
|
||||
hue = (c.b - c.r) / delta + 2.0;
|
||||
} else {
|
||||
hue = (c.r - c.g) / delta + 4.0;
|
||||
}
|
||||
hue *= 60.0;
|
||||
if (hue < 0.0) hue += 360.0;
|
||||
}
|
||||
|
||||
highp float sat = (xMax == 0.0) ? 0.0 : delta / xMax;
|
||||
return vec3(hue, sat, xMax);
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
highp vec4 color = zTextureSpec(SCREEN_TEXTURE, UV);
|
||||
highp vec3 gray = vec3(zGrayscale(color.rgb));
|
||||
highp vec3 hsv = rgb2hsv(color.rgb);
|
||||
|
||||
// Red is near 0 or 360 in hue
|
||||
bool is_red = hsv.x < RedHueRange || hsv.x > (360.0 - RedHueRange);
|
||||
bool saturated_enough = hsv.y > MinSaturation; // Avoid desaturated pinks/greys
|
||||
|
||||
if (is_red && saturated_enough) {
|
||||
COLOR = color;
|
||||
} else {
|
||||
COLOR = vec4(gray, color.a);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user