Files
tbd-station-14/Resources/Textures/Shaders/noir.swsl
slarticodefast 7d2d05b99c Fix noir shader in compability mode (#38080)
fix noir shader in compability mode
2025-06-05 14:52:39 +02:00

47 lines
1.3 KiB
Plaintext

// 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.0;
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);
}
}