initial unified color space implementation

This commit is contained in:
Valerie Wolfe 2024-05-13 16:26:00 -04:00
parent 7e8c6ca9e0
commit 9b9cf33236
5 changed files with 127 additions and 66 deletions

View file

@ -11,31 +11,11 @@ uniform float viewWidth, viewHeight;
varying vec2 texcoord;
#include "/module/color_depth.frag"
#include "/module/color.frag"
//#include "/module/color_depth.frag"
#include "/module/dof.frag"
#include "/module/interlace.frag"
// All components are in the range [0…1], including hue.
vec3 rgb2hsv(vec3 c)
{
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
// All components are in the range [0…1], including hue.
vec3 hsv2rgb(vec3 c)
{
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
const float steps = 4.0;
uniform vec3 palette[8];
@ -124,34 +104,14 @@ void main() {
newcoord = (floor(newcoord * view) + offset) / view;
#endif
vec3 color = texture2D(gcolor, newcoord).rgb;
color = to(color).xyz;
#if colorMode == MODE_HSV
color = rgb2hsv(color).xyz;
#endif
vec3 final;
#ifdef dithering
#if colorMode == MODE_HSV
vec3 filtered = vec3(dither(color.x, hueMax), dither(color.y, satMax), dither(color.z, valMax)).rgb;
final = hsv2rgb(filtered);
#else
final = vec3(dither(color.r, colormax.x), dither(color.g, colormax.y), dither(color.b, colormax.z));
#endif
#else
#if colorMode == MODE_HSV
vec3 filtered = vec3(lightnessStep(color.x, hueMax), lightnessStep(color.y, satMax), lightnessStep(color.z, valMax)).rgb;
final = hsv2rgb(filtered);
#else
final = vec3(lightnessStep(color.r, colormax.x), lightnessStep(color.g, colormax.y), lightnessStep(color.b, colormax.z)).rgb;
#endif
#endif
#if colorMode == MODE_RGB && colorDepth == 1
if(final.r == 1)
final = monoHigh;
else
final = monoLow;
#endif
#ifdef dithering
vec3 final = vec3(dither(color.x, firstMax), dither(color.y, secondMax), dither(color.z, thirdMax)).rgb;
#else
vec3 final = vec3(lightnessStep(color.x, firstMax), lightnessStep(color.y, secondMax), lightnessStep(color.z, thirdMax)).rgb;
#endif
final = from(final);
#ifdef interlacing
/* DRAWBUFFERS:01 */

View file

@ -21,20 +21,19 @@ value.pixelSize.16=Silly (16x)
screen.COLOR=Color
option.colorMode=Color Mode
value.colorMode.0=HSV
value.colorMode.1=RGB
value.colorMode.0=RGB
value.colorMode.1=HSV
value.colorMode.2=YIQ
value.colorMode.3=YUV
option.dithering=Dithering
option.colorDepth=RGB Depth
value.colorDepth.1=Monochrome
value.colorDepth.3=3-bit
value.colorDepth.6=6-bit
value.colorDepth.8=8-bit
value.colorDepth.12=12-bit
value.colorDepth.15=15-bit
value.colorDepth.18=18-bit
value.colorDepth.24=Truecolor
option.firstBits=First Value
suffix.firstBits=-bit
option.secondBits=Second Value
suffix.secondBits=-bit
option.thirdBits=Third Value
suffix.thirdBits=-bit
option.monoPalette=Mono Palette
value.monoPalette.0=Black & White

95
shaders/module/color.frag Normal file
View file

@ -0,0 +1,95 @@
#include "/var/color.glsl"
#define colorMode 1 // [0 1 2 3]
#define firstBits 2 // [1 2 3 4 5 6 7 8]
#define secondBits 2 // [1 2 3 4 5 6 7 8]
#define thirdBits 2 // [1 2 3 4 5 6 7 8]
float bit_max(int bits) { return pow(2, bits); }
float firstMax = bit_max(firstBits);
float secondMax = bit_max(secondBits);
float thirdMax = bit_max(thirdBits);
float luminance(vec3 color) {
return dot(color, vec3(0.299, 0.587, 0.114));
}
vec3 toHsv(vec3 rgb) {
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
vec4 p = mix(vec4(rgb.bg, K.wz), vec4(rgb.gb, K.xy), step(rgb.b, rgb.g));
vec4 q = mix(vec4(p.xyw, rgb.r), vec4(rgb.r, p.yzx), step(p.x, rgb.r));
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
vec3 fromHsv(vec3 hsv) {
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(hsv.xxx + K.xyz) * 6 - K.www);
return hsv.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), hsv.y);
}
vec3 toYiq(vec3 rgb) {
float y = luminance(rgb);
float i = dot(rgb, vec3(0.596, -.274, -.322));
float q = dot(rgb, vec3(0.211, -.523, 0.312));
return vec3(y, i, q);
}
vec3 fromYiq(vec3 yiq) {
float r = dot(yiq, vec3(1, 0.956, 0.619));
float g = dot(yiq, vec3(1, -.272, -.674));
float b = dot(yiq, vec3(1, -1.106, 1.703));
return vec3(r, g, b);
}
vec3 toYuv(vec3 rgb) {
float y = luminance(rgb);
float u = 0.492 * (rgb.b - y);
float v = 0.877 * (rgb.r - y);
return vec3(y, u, v);
}
vec3 fromYuv(vec3 yuv) {
float r = yuv.x + (1.140 * yuv.z);
float g = yuv.x - (0.395 * yuv.y) - (0.581 * yuv.z);
float b = yuv.x + (2.033 * yuv.y);
return vec3(r, g, b);
}
vec3 to(vec3 rgb) {
#if colorMode == COLOR_RGB
return rgb;
#elif colorMode == COLOR_HSV
return toHsv(rgb);
#elif colorMode == COLOR_YIQ
return toYiq(rgb);
#elif colorMode == COLOR_YUV
return toYuv(rgb);
#endif
}
vec3 from(vec3 color) {
#if colorMode == COLOR_RGB
return color;
#elif colorMode == COLOR_HSV
return fromHsv(color);
#elif colorMode == COLOR_YIQ
return fromYiq(color);
#elif colorMode == COLOR_YUV
return fromYuv(color);
#endif
}

View file

@ -1,13 +1,14 @@
sliders=pixelSize colorDepth hueBits satBits valBits vWarp worldRadius
# -- PROFILES --
profile.DEFAULT=pixelSize=2 colorMode=0 dithering hueBits=2 satBits=2 valBits=2 vWarp=0 !tWarp !hBlur !interlacing
profile.AEON=pixelSize=1 colorMode=0 dithering hueBits=3 satBits=2 valBits=2 vWarp=0 !tWarp !hBlur !interlacing
profile.DEFAULT=pixelSize=2 colorMode=1 dithering firstBits=2 secondBits=2 thirdBits=2 vWarp=0 !tWarp !hBlur !interlacing
profile.AEON=pixelSize=1 colorMode=1 dithering firstBits=3 secondBits=2 thirdBits=2 vWarp=0 !tWarp !hBlur !interlacing
profile.DOS=pixelSize=4 colorMode=1 dithering colorDepth=3 vWarp=1 !tWarp !hBlur !interlacing
profile.DOTMATRIX=pixelSize=4 colorMode=1 colorDepth=1 monoPalette=1 dithering vWarp=1 !tWarp !hBlur !interlacing
profile.OBRADINN=pixelSize=2 colorMode=1 colorDepth=1 monoPalette=0 dithering vWarp=0 !tWarp !hBlur !interlacing
profile.DOTMATRIX=pixelSize=4 colorMode=0 monoPalette=1 dithering vWarp=1 !tWarp !hBlur !interlacing
profile.EIGHTBIT=pixelSize=2 colorMode=0 dithering firstBits=3 secondBits=3 thirdBits=2 vWarp=0 !tWarp !hBlur !interlacing
profile.OBRADINN=pixelSize=2 colorMode=0 colorDepth=1 monoPalette=0 dithering vWarp=0 !tWarp !hBlur !interlacing
profile.PSX=pixelSize=2 colorMode=1 !dithering colorDepth=24 vWarp=2 tWarp !hBlur interlacing
profile.REALITY=pixelSize=2 colorMode=1 colorDepth=15 !dithering vWarp=0 !tWarp hBlur interlacing
profile.REALITY=pixelSize=2 colorMode=1 firstBits=5 secondBits=5 thirdBits=5 !dithering vWarp=0 !tWarp hBlur interlacing
profile.VR32=pixelSize=8 colorMode=1 !dithering colorDepth=1 monoPalette=2 vWarp=1 !tWarp !hBlur !interlacing
# -- SCREENS --
@ -16,7 +17,7 @@ screen=<profile> <empty> <empty> <empty> pixelSize <empty> [COLOR] [SCREEN] [CON
# colors
screen.COLOR.columns=3
screen.COLOR=colorMode dithering <empty> colorDepth <empty> monoPalette hueBits satBits valBits
screen.COLOR=colorMode dithering <empty> firstBits secondBits thirdBits
# screen effects
screen.SCREEN=signal wire interlacing scanline <empty> <empty> aberration

6
shaders/var/color.glsl Normal file
View file

@ -0,0 +1,6 @@
#define COLOR_RGB 0 // RGB colorspace
#define COLOR_HSV 1 // HSV colorspace
#define COLOR_YIQ 2 // YIQ colorspace
#define COLOR_YUV 3 // YUV colorspace