Created
July 1, 2022 22:04
-
-
Save m4rt1n0/a987ae8c82e5e658a2a945e3ed79263c to your computer and use it in GitHub Desktop.
Game Boy Camera shader for OBS ShaderFilter Plus
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Game Boy Camera shader for OBS ShaderFilter Plus plugin [https://github.com/Limeth/obs-shaderfilter-plus] | |
// A modified version of [https://www.shadertoy.com/view/ttsSzr] by yx | |
// Palettes from [https://www.deviantart.com/thewolfbunny64/art/Game-Boy-Palette-Set-Super-Game-Boy-Bash-879821261] | |
// Use .hlsl on Windows and .glsl on Linux | |
#pragma shaderfilter set mirror__description Mirror image | |
#pragma shaderfilter set mirror__default false | |
#pragma shaderfilter set preset_palette__description Preset palette | |
#pragma shaderfilter set preset_palette__default 0 | |
#pragma shaderfilter set preset_palette__min 0 | |
#pragma shaderfilter set preset_palette__max 35 | |
#pragma shaderfilter set use_custom_palette__description Use custom palette: | |
#pragma shaderfilter set use_custom_palette__default false | |
#pragma shaderfilter set color1__description Color 1 | |
#pragma shaderfilter set color1__default 081820FF | |
#pragma shaderfilter set color2__description Color 2 | |
#pragma shaderfilter set color2__default 346856FF | |
#pragma shaderfilter set color3__description Color 3 | |
#pragma shaderfilter set color3__default 88C070FF | |
#pragma shaderfilter set color4__description Color 4 | |
#pragma shaderfilter set color4__default E0F8D0FF | |
uniform bool mirror; | |
uniform int preset_palette; | |
uniform bool use_custom_palette; | |
// ShaderFilter Plus requires HLSL syntax | |
uniform float4 color1; | |
uniform float4 color2; | |
uniform float4 color3; | |
uniform float4 color4; | |
vec4 render(vec2 uv) | |
{ | |
// hardcoded Bayer filter | |
float bayer[64] = float[64]( | |
0., 32., 8., 40., 2., 34., 10., 42., | |
48., 16., 56., 24., 50., 18., 58., 26., | |
12., 44., 4., 36., 14., 46., 6., 38., | |
60., 28., 52., 20., 62., 30., 54., 22., | |
3., 35., 11., 43., 1., 33., 9., 41., | |
51., 19., 59., 27., 49., 17., 57., 25., | |
15., 47., 7., 39., 13., 45., 5., 37., | |
63., 31., 55., 23., 61., 29., 53., 21. | |
); | |
// custom palette | |
vec4 palette[4]; | |
palette[0] = color1; | |
palette[1] = color2; | |
palette[2] = color3; | |
palette[3] = color4; | |
// preset palettes | |
vec3 p[144]; | |
p[ 0] = vec3( 8, 24, 32)/255.; p[ 1] = vec3( 52,104, 86)/255.; p[ 2] = vec3(136,192,112)/255.; p[ 3] = vec3(224,248,208)/255.; // Shadertoy original | |
p[ 4] = vec3( 41, 65, 57)/255.; p[ 5] = vec3( 56, 89, 74)/255.; p[ 6] = vec3( 90,120, 65)/255.; p[ 7] = vec3(123,130, 16)/255.; // DMG pea soup | |
p[ 8] = vec3( 8, 24, 32)/255.; p[ 9] = vec3( 74, 81, 57)/255.; p[10] = vec3(140,146,106)/255.; p[11] = vec3(197,202,164)/255.; // GB Pocket | |
p[12] = vec3( 0, 80, 57)/255.; p[13] = vec3( 0,105, 74)/255.; p[14] = vec3( 0,153,115)/255.; p[15] = vec3( 0,178,132)/255.; // GB Light | |
p[16] = vec3( 48, 24, 80)/255.; p[17] = vec3(168, 40, 32)/255.; p[18] = vec3(216,144, 72)/255.; p[19] = vec3(248,232,200)/255.; // SGB 1-A | |
p[20] = vec3( 0, 0, 0)/255.; p[21] = vec3(176, 80, 16)/255.; p[22] = vec3(200,176,112)/255.; p[23] = vec3(216,216,192)/255.; // SGB 1-B | |
p[24] = vec3( 56, 56,152)/255.; p[25] = vec3(152, 56, 96)/255.; p[26] = vec3(232,152, 80)/255.; p[27] = vec3(248,192,248)/255.; // SGB 1-C | |
p[28] = vec3( 80, 24, 0)/255.; p[29] = vec3(248, 0, 0)/255.; p[30] = vec3(192,128, 72)/255.; p[31] = vec3(248,248,168)/255.; // SGB 1-D | |
p[32] = vec3( 88, 56, 32)/255.; p[33] = vec3(104,136, 64)/255.; p[34] = vec3(120,192,120)/255.; p[35] = vec3(248,216,176)/255.; // SGB 1-E | |
p[36] = vec3( 0, 64, 16)/255.; p[37] = vec3(168, 0, 0)/255.; p[38] = vec3(224,136, 80)/255.; p[39] = vec3(216,232,248)/255.; // SGB 1-F | |
p[40] = vec3(248,248, 88)/255.; p[41] = vec3(120,120, 0)/255.; p[42] = vec3( 0,160,232)/255.; p[43] = vec3( 0, 0, 80)/255.; // SGB 1-G | |
p[44] = vec3( 48, 24, 0)/255.; p[45] = vec3(128, 64, 0)/255.; p[46] = vec3(248,184,136)/255.; p[47] = vec3(248,232,224)/255.; // SGB 1-H | |
p[48] = vec3( 0, 0, 0)/255.; p[49] = vec3( 40,120, 0)/255.; p[50] = vec3(192,136, 72)/255.; p[51] = vec3(240,200,160)/255.; // SGB 2-A | |
p[52] = vec3( 80, 0, 88)/255.; p[53] = vec3(248, 48, 0)/255.; p[54] = vec3(248,232, 80)/255.; p[55] = vec3(248,248,248)/255.; // SGB 2-B | |
p[56] = vec3( 40, 40,152)/255.; p[57] = vec3(120, 48,232)/255.; p[58] = vec3(232,136, 36)/255.; p[59] = vec3(248,192,248)/255.; // SGB 2-C | |
p[60] = vec3( 0, 0, 80)/255.; p[61] = vec3(248, 48, 0)/255.; p[62] = vec3( 0,248, 0)/255.; p[63] = vec3(248,248,160)/255.; // SGB 2-D | |
p[64] = vec3( 16, 8, 16)/255.; p[65] = vec3( 40, 16, 96)/255.; p[66] = vec3(144,176,224)/255.; p[67] = vec3(248,200,128)/255.; // SGB 2-E | |
p[68] = vec3( 24, 0, 0)/255.; p[69] = vec3(160, 0, 0)/255.; p[70] = vec3(248,144, 80)/255.; p[71] = vec3(208,248,248)/255.; // SGB 2-F | |
p[72] = vec3( 0, 24, 0)/255.; p[73] = vec3(224,184,128)/255.; p[74] = vec3(224, 80, 64)/255.; p[75] = vec3(104, 84, 56)/255.; // SGB 2-G | |
p[76] = vec3( 0, 0, 0)/255.; p[77] = vec3(112,112,112)/255.; p[78] = vec3(184,184,184)/255.; p[79] = vec3(248,248,248)/255.; // SGB 2-H | |
p[ 80] = vec3( 48, 72, 96)/255.; p[ 81] = vec3(248, 96, 40)/255.; p[ 82] = vec3(112,192,192)/255.; p[ 83] = vec3(248,208,152)/255.; // SGB 3-A | |
p[ 84] = vec3( 0, 16, 16)/255.; p[ 85] = vec3( 0, 80, 0)/255.; p[ 86] = vec3(224,128, 32)/255.; p[ 87] = vec3(216,216,192)/255.; // SGB 3-B | |
p[ 88] = vec3( 32, 32, 88)/255.; p[ 89] = vec3( 0,184,248)/255.; p[ 90] = vec3(248,248,120)/255.; p[ 91] = vec3(224,168,200)/255.; // SGB 3-C | |
p[ 92] = vec3( 0, 0, 0)/255.; p[ 93] = vec3( 8,200, 0)/255.; p[ 94] = vec3(224,168,120)/255.; p[ 95] = vec3(240,248,184)/255.; // SGB 3-D | |
p[ 96] = vec3( 80, 72,112)/255.; p[ 97] = vec3(176,120, 32)/255.; p[ 98] = vec3(224,176,104)/255.; p[ 99] = vec3(248,248,192)/255.; // SGB 3-E | |
p[100] = vec3( 64, 64, 64)/255.; p[101] = vec3(248,208, 0)/255.; p[102] = vec3(248,104,248)/255.; p[103] = vec3(120,120,200)/255.; // SGB 3-F | |
p[104] = vec3( 56, 0, 0)/255.; p[105] = vec3(200, 48, 56)/255.; p[106] = vec3(248,248,248)/255.; p[107] = vec3( 96,216, 80)/255.; // SGB 3-G | |
p[108] = vec3( 8, 24, 0)/255.; p[109] = vec3( 72,136, 24)/255.; p[110] = vec3(120,200, 56)/255.; p[111] = vec3(224,248,160)/255.; // SGB 3-H | |
p[112] = vec3( 0, 0,120)/255.; p[113] = vec3(208, 0,208)/255.; p[114] = vec3(120,168,248)/255.; p[115] = vec3(240,168,104)/255.; // SGB 4-A | |
p[116] = vec3( 24, 8, 8)/255.; p[117] = vec3( 64,120, 56)/255.; p[118] = vec3(232,160, 96)/255.; p[119] = vec3(240,232,240)/255.; // SGB 4-B | |
p[120] = vec3( 8, 0, 0)/255.; p[121] = vec3(152,156,224)/255.; p[122] = vec3(216,160,208)/255.; p[123] = vec3(248,224,224)/255.; // SGB 4-C | |
p[124] = vec3( 8, 32, 72)/255.; p[125] = vec3( 72,104,120)/255.; p[126] = vec3(144,200,200)/255.; p[127] = vec3(248,248,184)/255.; // SGB 4-D | |
p[128] = vec3( 0, 32, 48)/255.; p[129] = vec3(120, 88,136)/255.; p[130] = vec3(224,168,120)/255.; p[131] = vec3(248,216,168)/255.; // SGB 4-E | |
p[132] = vec3( 56, 0, 0)/255.; p[133] = vec3(128, 0,160)/255.; p[134] = vec3(216,128,216)/255.; p[135] = vec3(184,208,208)/255.; // SGB 4-F | |
p[136] = vec3( 0,128, 96)/255.; p[137] = vec3( 40, 16, 0)/255.; p[138] = vec3(184, 32, 88)/255.; p[139] = vec3(176,224, 24)/255.; // SGB 4-G | |
p[140] = vec3( 64, 80, 40)/255.; p[141] = vec3(128,136, 64)/255.; p[142] = vec3(184,192, 88)/255.; p[143] = vec3(248,248,200)/255.; // SGB 4-H | |
vec4 res; | |
res.xy = vec2(128,112); // "square" resolution | |
res.zw = vec2(res.y*builtin_uv_size.x/builtin_uv_size.y,res.y); // widescreen resolution | |
vec2 new_uv = uv; | |
if (mirror) uv.x = 1.-uv.x; // optional mirror selfie mode | |
new_uv = floor(uv*res.zw) + 0.5; | |
int value = 0; | |
if (abs(new_uv.x*2.-res.z) < res.x) | |
{ | |
vec3 image_color = image.Sample(builtin_texture_sampler, new_uv/res.zw).xyz; | |
float gray = dot(image_color, vec3(0.2126,0.7152,0.0722)); | |
int x = int(new_uv.x)%8; | |
int y = int(new_uv.y)%8; | |
float dither = bayer[y*8+x]/64.; | |
value = int(floor(gray*3.+dither)); | |
} | |
if (use_custom_palette) { | |
return palette[value]; | |
} else { | |
return vec4(p[preset_palette * 4 + value], 1); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Game Boy Camera shader for OBS ShaderFilter Plus plugin [https://github.com/Limeth/obs-shaderfilter-plus] | |
// A modified version of [https://www.shadertoy.com/view/ttsSzr] by yx | |
// Palettes from [https://www.deviantart.com/thewolfbunny64/art/Game-Boy-Palette-Set-Super-Game-Boy-Bash-879821261] | |
// Use .hlsl on Windows and .glsl on Linux | |
#pragma shaderfilter set mirror__description Mirror image | |
#pragma shaderfilter set mirror__default false | |
#pragma shaderfilter set preset_palette__description Preset palette | |
#pragma shaderfilter set preset_palette__default 0 | |
#pragma shaderfilter set preset_palette__min 0 | |
#pragma shaderfilter set preset_palette__max 35 | |
#pragma shaderfilter set use_custom_palette__description Use custom palette: | |
#pragma shaderfilter set use_custom_palette__default false | |
#pragma shaderfilter set color1__description Color 1 | |
#pragma shaderfilter set color1__default 081820FF | |
#pragma shaderfilter set color2__description Color 2 | |
#pragma shaderfilter set color2__default 346856FF | |
#pragma shaderfilter set color3__description Color 3 | |
#pragma shaderfilter set color3__default 88C070FF | |
#pragma shaderfilter set color4__description Color 4 | |
#pragma shaderfilter set color4__default E0F8D0FF | |
uniform bool mirror; | |
uniform int preset_palette; | |
uniform bool use_custom_palette; | |
uniform float4 color1; | |
uniform float4 color2; | |
uniform float4 color3; | |
uniform float4 color4; | |
float4 render(float2 uv) | |
{ | |
// hardcoded Bayer filter | |
float bayer[64] = { | |
0., 32., 8., 40., 2., 34., 10., 42., | |
48., 16., 56., 24., 50., 18., 58., 26., | |
12., 44., 4., 36., 14., 46., 6., 38., | |
60., 28., 52., 20., 62., 30., 54., 22., | |
3., 35., 11., 43., 1., 33., 9., 41., | |
51., 19., 59., 27., 49., 17., 57., 25., | |
15., 47., 7., 39., 13., 45., 5., 37., | |
63., 31., 55., 23., 61., 29., 53., 21. | |
}; | |
// custom palette | |
float4 palette[4]; | |
palette[0] = color1; | |
palette[1] = color2; | |
palette[2] = color3; | |
palette[3] = color4; | |
// preset palettes | |
float3 p[144]; | |
p[ 0] = float3( 8, 24, 32)/255.; p[ 1] = float3( 52,104, 86)/255.; p[ 2] = float3(136,192,112)/255.; p[ 3] = float3(224,248,208)/255.; // Shadertoy original | |
p[ 4] = float3( 41, 65, 57)/255.; p[ 5] = float3( 56, 89, 74)/255.; p[ 6] = float3( 90,120, 65)/255.; p[ 7] = float3(123,130, 16)/255.; // DMG pea soup | |
p[ 8] = float3( 8, 24, 32)/255.; p[ 9] = float3( 74, 81, 57)/255.; p[10] = float3(140,146,106)/255.; p[11] = float3(197,202,164)/255.; // GB Pocket | |
p[12] = float3( 0, 80, 57)/255.; p[13] = float3( 0,105, 74)/255.; p[14] = float3( 0,153,115)/255.; p[15] = float3( 0,178,132)/255.; // GB Light | |
p[16] = float3( 48, 24, 80)/255.; p[17] = float3(168, 40, 32)/255.; p[18] = float3(216,144, 72)/255.; p[19] = float3(248,232,200)/255.; // SGB 1-A | |
p[20] = float3( 0, 0, 0)/255.; p[21] = float3(176, 80, 16)/255.; p[22] = float3(200,176,112)/255.; p[23] = float3(216,216,192)/255.; // SGB 1-B | |
p[24] = float3( 56, 56,152)/255.; p[25] = float3(152, 56, 96)/255.; p[26] = float3(232,152, 80)/255.; p[27] = float3(248,192,248)/255.; // SGB 1-C | |
p[28] = float3( 80, 24, 0)/255.; p[29] = float3(248, 0, 0)/255.; p[30] = float3(192,128, 72)/255.; p[31] = float3(248,248,168)/255.; // SGB 1-D | |
p[32] = float3( 88, 56, 32)/255.; p[33] = float3(104,136, 64)/255.; p[34] = float3(120,192,120)/255.; p[35] = float3(248,216,176)/255.; // SGB 1-E | |
p[36] = float3( 0, 64, 16)/255.; p[37] = float3(168, 0, 0)/255.; p[38] = float3(224,136, 80)/255.; p[39] = float3(216,232,248)/255.; // SGB 1-F | |
p[40] = float3(248,248, 88)/255.; p[41] = float3(120,120, 0)/255.; p[42] = float3( 0,160,232)/255.; p[43] = float3( 0, 0, 80)/255.; // SGB 1-G | |
p[44] = float3( 48, 24, 0)/255.; p[45] = float3(128, 64, 0)/255.; p[46] = float3(248,184,136)/255.; p[47] = float3(248,232,224)/255.; // SGB 1-H | |
p[48] = float3( 0, 0, 0)/255.; p[49] = float3( 40,120, 0)/255.; p[50] = float3(192,136, 72)/255.; p[51] = float3(240,200,160)/255.; // SGB 2-A | |
p[52] = float3( 80, 0, 88)/255.; p[53] = float3(248, 48, 0)/255.; p[54] = float3(248,232, 80)/255.; p[55] = float3(248,248,248)/255.; // SGB 2-B | |
p[56] = float3( 40, 40,152)/255.; p[57] = float3(120, 48,232)/255.; p[58] = float3(232,136, 36)/255.; p[59] = float3(248,192,248)/255.; // SGB 2-C | |
p[60] = float3( 0, 0, 80)/255.; p[61] = float3(248, 48, 0)/255.; p[62] = float3( 0,248, 0)/255.; p[63] = float3(248,248,160)/255.; // SGB 2-D | |
p[64] = float3( 16, 8, 16)/255.; p[65] = float3( 40, 16, 96)/255.; p[66] = float3(144,176,224)/255.; p[67] = float3(248,200,128)/255.; // SGB 2-E | |
p[68] = float3( 24, 0, 0)/255.; p[69] = float3(160, 0, 0)/255.; p[70] = float3(248,144, 80)/255.; p[71] = float3(208,248,248)/255.; // SGB 2-F | |
p[72] = float3( 0, 24, 0)/255.; p[73] = float3(224,184,128)/255.; p[74] = float3(224, 80, 64)/255.; p[75] = float3(104, 84, 56)/255.; // SGB 2-G | |
p[76] = float3( 0, 0, 0)/255.; p[77] = float3(112,112,112)/255.; p[78] = float3(184,184,184)/255.; p[79] = float3(248,248,248)/255.; // SGB 2-H | |
p[ 80] = float3( 48, 72, 96)/255.; p[ 81] = float3(248, 96, 40)/255.; p[ 82] = float3(112,192,192)/255.; p[ 83] = float3(248,208,152)/255.; // SGB 3-A | |
p[ 84] = float3( 0, 16, 16)/255.; p[ 85] = float3( 0, 80, 0)/255.; p[ 86] = float3(224,128, 32)/255.; p[ 87] = float3(216,216,192)/255.; // SGB 3-B | |
p[ 88] = float3( 32, 32, 88)/255.; p[ 89] = float3( 0,184,248)/255.; p[ 90] = float3(248,248,120)/255.; p[ 91] = float3(224,168,200)/255.; // SGB 3-C | |
p[ 92] = float3( 0, 0, 0)/255.; p[ 93] = float3( 8,200, 0)/255.; p[ 94] = float3(224,168,120)/255.; p[ 95] = float3(240,248,184)/255.; // SGB 3-D | |
p[ 96] = float3( 80, 72,112)/255.; p[ 97] = float3(176,120, 32)/255.; p[ 98] = float3(224,176,104)/255.; p[ 99] = float3(248,248,192)/255.; // SGB 3-E | |
p[100] = float3( 64, 64, 64)/255.; p[101] = float3(248,208, 0)/255.; p[102] = float3(248,104,248)/255.; p[103] = float3(120,120,200)/255.; // SGB 3-F | |
p[104] = float3( 56, 0, 0)/255.; p[105] = float3(200, 48, 56)/255.; p[106] = float3(248,248,248)/255.; p[107] = float3( 96,216, 80)/255.; // SGB 3-G | |
p[108] = float3( 8, 24, 0)/255.; p[109] = float3( 72,136, 24)/255.; p[110] = float3(120,200, 56)/255.; p[111] = float3(224,248,160)/255.; // SGB 3-H | |
p[112] = float3( 0, 0,120)/255.; p[113] = float3(208, 0,208)/255.; p[114] = float3(120,168,248)/255.; p[115] = float3(240,168,104)/255.; // SGB 4-A | |
p[116] = float3( 24, 8, 8)/255.; p[117] = float3( 64,120, 56)/255.; p[118] = float3(232,160, 96)/255.; p[119] = float3(240,232,240)/255.; // SGB 4-B | |
p[120] = float3( 8, 0, 0)/255.; p[121] = float3(152,156,224)/255.; p[122] = float3(216,160,208)/255.; p[123] = float3(248,224,224)/255.; // SGB 4-C | |
p[124] = float3( 8, 32, 72)/255.; p[125] = float3( 72,104,120)/255.; p[126] = float3(144,200,200)/255.; p[127] = float3(248,248,184)/255.; // SGB 4-D | |
p[128] = float3( 0, 32, 48)/255.; p[129] = float3(120, 88,136)/255.; p[130] = float3(224,168,120)/255.; p[131] = float3(248,216,168)/255.; // SGB 4-E | |
p[132] = float3( 56, 0, 0)/255.; p[133] = float3(128, 0,160)/255.; p[134] = float3(216,128,216)/255.; p[135] = float3(184,208,208)/255.; // SGB 4-F | |
p[136] = float3( 0,128, 96)/255.; p[137] = float3( 40, 16, 0)/255.; p[138] = float3(184, 32, 88)/255.; p[139] = float3(176,224, 24)/255.; // SGB 4-G | |
p[140] = float3( 64, 80, 40)/255.; p[141] = float3(128,136, 64)/255.; p[142] = float3(184,192, 88)/255.; p[143] = float3(248,248,200)/255.; // SGB 4-H | |
float4 res; | |
res.xy = float2(128,112); // "square" resolution | |
res.zw = float2(res.y*builtin_uv_size.x/builtin_uv_size.y,res.y); // widescreen resolution | |
float2 new_uv = uv; | |
if (mirror) uv.x = 1.-uv.x; // optional mirror selfie mode | |
new_uv = floor(uv*res.zw) + 0.5; | |
int value = 0; | |
if (abs(new_uv.x*2.-res.z) < res.x) | |
{ | |
float3 image_color = image.Sample(builtin_texture_sampler, new_uv/res.zw).xyz; | |
float gray = dot(image_color, float3(0.2126,0.7152,0.0722)); | |
int x = int(new_uv.x)%8; | |
int y = int(new_uv.y)%8; | |
float dither = bayer[y*8+x]/64.; | |
value = int(floor(gray*3.+dither)); | |
} | |
if (use_custom_palette) { | |
return palette[value]; | |
} else { | |
return float4(p[preset_palette * 4 + value], 1); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment