slang-shaders/misc/shaders/ega.slang

165 lines
3.3 KiB
Plaintext
Raw Normal View History

#version 450
layout(push_constant) uniform Push
{
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
uint FrameCount;
2023-05-13 22:21:57 +10:00
float palette, color_enhance;
} params;
2023-05-13 22:21:57 +10:00
#pragma parameter palette "Choose palette Hercules/CGA/EGA" 2.0 0.0 2.0 1.0
#define palette params.palette
#pragma parameter color_enhance "Color Enchance" 1.4 1.0 4.0 0.05
#define color_enhance params.color_enhance
#define _ 0.0
#define o (1./3.)
#define b (2./3.)
#define B 1.0
2023-05-13 22:21:57 +10:00
#define SourceSize params.SourceSize
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
void main()
{
gl_Position = global.MVP * Position;
vTexCoord = TexCoord*1.0001;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
// Color lookup table (RGBI palette with brown fix)
const vec3 rgbi_palette[19] =
{
2023-05-13 22:21:57 +10:00
vec3(_, _, _), // cga
vec3(B, B, B), // cga white
vec3(o, B, B), // cga cyan
vec3(B, o, B), // cga pink
vec3(_, _, b),
vec3(_, b, _),
vec3(_, b, _),
vec3(_, b, _),
vec3(_, b, _),
vec3(_, b, b),
vec3(b, _, _),
vec3(b, _, b),
vec3(b, o, _),
vec3(b, b, b),
vec3(o, o, o),
vec3(o, o, B),
vec3(o, B, o),
vec3(B, o, o),
vec3(B, B, o),
2023-05-13 22:21:57 +10:00
};
const vec3 cga_palette[4] =
{
vec3(_, _, _), // cga
vec3(o, B, B), // cga cyan
vec3(B, o, B), // cga pink
vec3(B, B, B), // cga white
};
const vec3 simcga_palette[2] =
{
vec3(_, _, _), // black
vec3(o, b, o), // green
};
// Came off the wikipedia(R) article for Ordered_Dithering
const int dithertable[16] =
{
1, 9, 3,11,
13, 5,15, 7,
4,12, 2,10,
16, 8,14, 6,
};
// Compare vector distances and return nearest RGBI color
vec3 nearest_rgbi (vec3 original)
{
float dst;
float min_dst = 2.0;
int idx = 0;
2023-05-13 22:21:57 +10:00
int set; if (palette == 2.0)set = 19; else if (palette == 1.0) set = 4;else if (palette == 1.0) set = 2;
for (int i=0; i<set; i++)
{
dst = distance(original, rgbi_palette[i]);
if (dst < min_dst)
{
min_dst = dst;
idx = i;
}
}
2023-05-13 22:21:57 +10:00
if (palette == 2.0) return rgbi_palette[idx];
else if (palette == 1.0) return cga_palette[idx];
else if (palette == 0.0) return simcga_palette[idx];
}
float modu(float x, float y)
{
return x - y * floor(x/y);
}
2023-05-13 22:21:57 +10:00
void main()
{
vec3 color = texture(Source, vTexCoord.xy).rgb;
// leilei - dither
vec2 res;
vec2 tex=vTexCoord.xy;
res.x = SourceSize.x;
if (SourceSize.y < 900.0)
res.y = SourceSize.y;
else
res.y = SourceSize.y / 2.0;
int ohyes;
int i;
vec2 ditheu = tex.xy * res.xy;
int ditdex = int(modu(ditheu.x, 4))*4 + int(modu(ditheu.y, 4)); // 4x4!
// looping through a lookup table matrix
for (i = ditdex; i < (ditdex+16); i = i+1)
ohyes = dithertable[i-15] * 2 - 21;
ohyes = ohyes - 6;
color *= 255.0;
color += ohyes;
color /= 255.0;
2023-05-13 22:21:57 +10:00
vec3 final = nearest_rgbi(color*color_enhance);
FragColor = vec4(final, 1.0);
}