add bayer-matrix, gendither and gdapt shaders

This commit is contained in:
hunterk 2017-01-06 12:55:29 -06:00
parent 7c2c7406ab
commit 5f1b86f316
7 changed files with 378 additions and 0 deletions

View file

@ -0,0 +1,4 @@
shaders = 1
shader0 = shaders/bayer-matrix-dithering.slang
filter_linear0 = false

11
dithering/gdapt.slangp Normal file
View file

@ -0,0 +1,11 @@
shaders = 2
shader0 = shaders/gdapt/gdapt-pass0.slang
filter_linear0 = false
scale_type0 = source
scale0 = 1.0
shader1 = shaders/gdapt/gdapt-pass1.slang
filter_linear1 = false
scale_type1 = source
scale1 = 1.0

View file

@ -0,0 +1,4 @@
shaders = 1
shader0 = shaders/gendither.slang
filter_linear0 = false

View file

@ -0,0 +1,87 @@
#version 450
// 8x8 Bayer matrix dithering
// by Martins Upitis
// license: "All the content here is and will be free to use for everyone, but a donation is always nice."
// url: http://devlog-martinsh.blogspot.com/2011/03/glsl-8x8-bayer-matrix-dithering.html
// adapted for RetroArch by hunterk
layout(push_constant) uniform Push
{
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
uint FrameCount;
float animate;
float dither_size;
} params;
#pragma parameter animate "Dithering Animation" 0.0 0.0 1.0 1.0
#pragma parameter dither_size "Dither Size" 0.0 0.0 0.95 0.05
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
float find_closest(int x, int y, float c0)
{
int dither[8][8] = {
{ 0, 32, 8, 40, 2, 34, 10, 42}, /* 8x8 Bayer ordered dithering */
{48, 16, 56, 24, 50, 18, 58, 26}, /* pattern. Each input pixel */
{12, 44, 4, 36, 14, 46, 6, 38}, /* is scaled to the 0..63 range */
{60, 28, 52, 20, 62, 30, 54, 22}, /* before looking in this table */
{ 3, 35, 11, 43, 1, 33, 9, 41}, /* to determine the action. */
{51, 19, 59, 27, 49, 17, 57, 25},
{15, 47, 7, 39, 13, 45, 5, 37},
{63, 31, 55, 23, 61, 29, 53, 21} };
float limit = 0.0;
if(x < 8)
{
limit = (dither[x][y]+1)/64.0;
}
if(c0 < limit)
return 0.0;
return 1.0;
}
#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;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
void main()
{
float Scale = 3.0 + mod(2.0 * params.FrameCount, 32.0) * params.animate + params.dither_size;
vec4 lum = vec4(0.299, 0.587, 0.114, 0);
float grayscale = dot(texture(Source, vTexCoord), lum);
vec3 rgb = texture(Source, vTexCoord).rgb;
vec2 xy = (vTexCoord * params.OutputSize.xy) * Scale;
int x = int(mod(xy.x, 8));
int y = int(mod(xy.y, 8));
vec3 finalRGB;
finalRGB.r = find_closest(x, y, rgb.r);
finalRGB.g = find_closest(x, y, rgb.g);
finalRGB.b = find_closest(x, y, rgb.b);
float final = find_closest(x, y, grayscale);
FragColor = vec4(finalRGB, 1.0);
}

View file

@ -0,0 +1,78 @@
#version 450
/*
Genesis Dithering and Pseudo Transparency Shader v1.3 - Pass 0
by Sp00kyFox, 2014
Neighbor anaylsis via dot product of the difference vectors.
*/
layout(push_constant) uniform Push
{
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
uint FrameCount;
float MODE;
float PWR;
} params;
#pragma parameter MODE "GDAPT Monochrome Analysis" 0.0 0.0 1.0 1.0
#pragma parameter PWR "GDAPT Color Metric Exp" 2.0 0.0 10.0 0.1
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
#define dot(x,y) clamp(dot(x,y), 0.0, 1.0) // NVIDIA Fix
#define TEX(dx,dy) texture(Source, vTexCoord+vec2((dx),(dy))*t1).xyz
// Reference: http://www.compuphase.com/cmetric.htm
float eq(vec3 A, vec3 B)
{
vec3 diff = A-B;
float ravg = (A.x + B.x) * 0.5;
diff *= diff * vec3(2.0 + ravg, 4.0, 3.0 - ravg);
return pow( smoothstep(3.0, 0.0, sqrt(diff.x + diff.y + diff.z)), params.PWR );
}
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
layout(location = 1) out vec2 t1;
void main()
{
gl_Position = global.MVP * vec4(Position.xy, 0.0, 1.0);
vTexCoord = TexCoord;
t1 = params.SourceSize.zw;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 1) in vec2 t1;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
void main()
{
vec3 C = TEX( 0, 0);
vec3 L = TEX(-1, 0);
vec3 R = TEX( 1, 0);
float tag = 0.0;
if(params.MODE > 0.5){
tag = ((L == R) && (C != L)) ? 1.0 : 0.0;
}
else{
tag = dot(normalize(C-L), normalize(C-R)) * eq(L,R);
}
FragColor = vec4(C, tag);
}

View file

@ -0,0 +1,93 @@
#version 450
/*
Genesis Dithering and Pseudo Transparency Shader v1.3 - Pass 1
by Sp00kyFox, 2014
Blends pixels based on detected dithering patterns.
*/
layout(push_constant) uniform Push
{
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
uint FrameCount;
float STEPS;
float DEBUG;
} params;
#pragma parameter STEPS "GDAPT Error Prevention LVL" 1.0 0.0 5.0 1.0
#pragma parameter DEBUG "GDAPT Adjust View" 0.0 0.0 1.0 1.0
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
#define TEX(dx,dy) texture(Source, vTexCoord+vec2((dx),(dy))*t1)
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
layout(location = 1) out vec2 t1;
void main()
{
gl_Position = global.MVP * vec4(Position.xy, 0.0, 1.0);
vTexCoord = TexCoord;
t1 = params.SourceSize.zw;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 1) in vec2 t1;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
void main()
{
vec4 C = TEX( 0, 0);
vec4 L = TEX(-1, 0);
vec4 R = TEX( 1, 0);
float str = 0.0;
if(params.STEPS == 0.0){
str = C.w;
}
else if(params.STEPS == 1.0){
str = min(max(L.w, R.w), C.w);
}
else if(params.STEPS == 2.0){
str = min(max(min(max(TEX(-2,0).w, R.w), L.w), min(R.w, TEX(2,0).w)), C.w);
}
else if(params.STEPS == 3.0){
float tmp = min(R.w, TEX(2,0).w);
str = min(max(min(max(min(max(TEX(-3,0).w, R.w), TEX(-2,0).w), tmp), L.w), min(tmp, TEX(3,0).w)), C.w);
}
else if(params.STEPS == 4.0){
float tmp1 = min(R.w, TEX(2,0).w);
float tmp2 = min(tmp1, TEX(3,0).w);
str = min(max(min(max(min(max(min(max(TEX(-4,0).w, R.w), TEX(-3,0).w), tmp1), TEX(-2,0).w), tmp2), L.w), min(tmp2, TEX(4,0).w)), C.w);
}
else{
float tmp1 = min(R.w, TEX(2,0).w);
float tmp2 = min(tmp1, TEX(3,0).w);
float tmp3 = min(tmp2, TEX(4,0).w);
str = min(max(min(max(min(max(min(max(min(max(TEX(-5,0).w, R.w), TEX(-4,0).w), tmp1), TEX(-3,0).w), tmp2), TEX(-2,0).w), tmp3), L.w), min(tmp3, TEX(5,0).w)), C.w);
}
if(params.DEBUG > 0.5)
FragColor = vec4(str);
float sum = L.w + R.w;
float wght = max(L.w, R.w);
wght = (wght == 0.0) ? 1.0 : sum/wght;
FragColor = vec4(mix(C.xyz, (wght*C.xyz + L.w*L.xyz + R.w*R.xyz)/(wght + sum), str), 1.0);
}

View file

@ -0,0 +1,101 @@
#version 450
// Gendither
//
// Copyright (C) 2013-2014 leilei
// adapted for slang format by hunterk
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version.
layout(push_constant) uniform Push
{
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
uint FrameCount;
} params;
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
// This table is a lazy jailbar pattern
int erroredtable[16] = {
0,1,0,1,
16,15,16,15,
0,1,0,1,
16,15,16,15
};
#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;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
void main()
{
vec3 final = texture(Source, vTexCoord).rgb;
vec2 ditheu = vTexCoord.xy * params.SourceSize.xy;
// Dither
int ditdex = int(mod(ditheu.x, 4.0)) * 4 + int(mod(ditheu.y, 4.0)); // 4x4!
ivec3 color;
ivec3 colord;
color.r = int(final.r) * 224;
color.g = int(final.g) * 224;
color.b = int(final.b) * 224;
int yeh = 0;
int ohyes = 0;
// looping through a lookup table matrix
for (yeh=ditdex; yeh<(ditdex+16); yeh++) ohyes = erroredtable[yeh-15];
colord.r = color.r + ohyes;
colord.g = color.g + ohyes;
colord.b = color.b + ohyes;
final.rgb += colord.rgb * 0.003921568627451; // divide by 255, i don't trust em
// Reduce color depth
float why = 1.0;
vec3 reduceme = vec3(1.0);
float radooct = 4.4; // 32 is usually the proper value // 4.4 was eyeballed
reduceme.r = pow(final.r, why);
reduceme.r *= radooct;
reduceme.r = int(floor(reduceme.r));
reduceme.r /= radooct;
reduceme.r = pow(reduceme.r, why);
reduceme.g = pow(final.g, why);
reduceme.g *= radooct;
reduceme.g = int(floor(reduceme.g));
reduceme.g /= radooct;
reduceme.g = pow(reduceme.g, why);
reduceme.b = pow(final.b, why);
reduceme.b *= radooct;
reduceme.b = int(floor(reduceme.b));
reduceme.b /= radooct;
reduceme.b = pow(reduceme.b, why);
// Brightness cap
reduceme.rgb = clamp(reduceme.rgb, vec3(0.0), vec3(0.875));
FragColor = vec4(reduceme.rgb, 1.0);
}