Skip to content

Instantly share code, notes, and snippets.

@TuxSH
Created October 11, 2023 21:58
Show Gist options
  • Save TuxSH/1d58807e1beb86646ac1ff112da908ef to your computer and use it in GitHub Desktop.
Save TuxSH/1d58807e1beb86646ac1ff112da908ef to your computer and use it in GitHub Desktop.
sp101-color.glsl
#version 450
/*
Shader Modified: Pokefan531
Color Mangler
Author: hunterk
License: Public domain
*/
// Shader that replicates the LCD Colorspace from a Gameboy SP 101 (backlit version) --
// (Note: This is also very close to what DS-Lite and DSi line colorspace looks)
#pragma parameter mode "Color Profile (1=sRGB, 2=DCI, 3=Rec2020)" 1.0 1.0 3.0 1.0
#pragma parameter white_toggle "Toggle White Balance" 1.0 0.0 1.0 1.0
#define target_gamma 2.0
#define display_gamma 2.0
#if defined(VERTEX)
#if __VERSION__ >= 130
#define COMPAT_VARYING out
#define COMPAT_ATTRIBUTE in
#define COMPAT_TEXTURE texture
#else
#define COMPAT_VARYING varying
#define COMPAT_ATTRIBUTE attribute
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
COMPAT_ATTRIBUTE vec4 VertexCoord;
COMPAT_ATTRIBUTE vec4 COLOR;
COMPAT_ATTRIBUTE vec4 TexCoord;
COMPAT_VARYING vec4 COL0;
COMPAT_VARYING vec4 TEX0;
uniform mat4 MVPMatrix;
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
// compatibility #defines
#define vTexCoord TEX0.xy
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutSize vec4(OutputSize, 1.0 / OutputSize)
void main()
{
gl_Position = MVPMatrix * VertexCoord;
COL0 = COLOR;
TEX0.xy = TexCoord.xy;
}
#elif defined(FRAGMENT)
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out COMPAT_PRECISION vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
COMPAT_VARYING vec4 TEX0;
// in variables go here as COMPAT_VARYING whatever
// compatibility #defines
#define Source Texture
#define vTexCoord TEX0.xy
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutSize vec4(OutputSize, 1.0 / OutputSize)
/*
We'll define our color weights in this pattern:
r, rg, rb, 0.0, //red channel
gr, g, gb, 0.0, //green channel
br, bg, b, 0.0, //blue channel
blr, blg, blb, lum //alpha channel; we'll hide lum at the end, too
*/
const COMPAT_PRECISION mat4 NDS_sRGB = mat4(
0.86, 0.03, 0.0025, 0.0, //red channel
0.10, 0.745, -0.03, 0.0, //green channel
-0.06, 0.0675, 1.0275, 0.0, //blue channel
0.0, 0.0, 0.0, 0.97 //alpha channel
);
const COMPAT_PRECISION mat4 NDS_sRGB_white = mat4(
0.955, 0.0375, 0.0025, 0.0, //red channel
0.11, 0.885, -0.03, 0.0, //green channel
-0.065, 0.0775, 1.0275, 0.0, //blue channel
0.0, 0.0, 0.0, 0.94 //alpha channel
);
const COMPAT_PRECISION mat4 NDS_DCI = mat4(
0.725, 0.06, 0.02, 0.0, //red channel
0.215, 0.73, 0.0225, 0.0, //green channel
-0.04, 0.065, 0.9575, 0.0, //blue channel
0.0, 0.0, 0.0, 1.0 //alpha channel
);
const COMPAT_PRECISION mat4 NDS_DCI_white = mat4(
0.805, 0.07, 0.02, 0.0, //red channel
0.235, 0.8575, 0.0225, 0.0, //green channel
-0.04, 0.0725, 0.9575, 0.0, //blue channel
0.0, 0.0, 0.0, 0.96 //alpha channel
);
const COMPAT_PRECISION mat4 NDS_Rec2020 = mat4(
0.56, 0.091, 0.02, 0.0, //red channel
0.31, 0.695, 0.035, 0.0, //green channel
0.0275, 0.07, 0.945, 0.0, //blue channel
0.0, 0.0, 0.0, 1.0 //alpha channel
);
const COMPAT_PRECISION mat4 NDS_Rec2020_white = mat4(
0.625, 0.105, 0.02, 0.0, //red channel
0.345, 0.815, 0.035, 0.0, //green channel
0.03, 0.08, 0.945, 0.0, //blue channel
0.0, 0.0, 0.0, 1.0 //alpha channel
);
#ifdef PARAMETER_UNIFORM
// All parameter floats need to have COMPAT_PRECISION in front of them
uniform COMPAT_PRECISION float mode;
uniform COMPAT_PRECISION float white_toggle;
#else
#define mode 1.0
#define white_toggle 1.0
#endif
void do_color_transformation(in mat4 profile)
{
// bring out our stored luminance value
float lum = profile[3].w;
// our adjustments need to happen in linear gamma
vec4 screen = pow(COMPAT_TEXTURE(Source, vTexCoord), vec4(target_gamma)).rgba;
screen = clamp(screen * lum, 0.0, 1.0);
screen = profile * screen;
FragColor = pow(screen, vec4(1.0 / display_gamma));
}
void main()
{
if (mode == 1.0) do_color_transformation(white_toggle == 0.0 ? NDS_sRGB : NDS_sRGB_white);
else if (mode == 2.0) do_color_transformation(white_toggle == 0.0 ? NDS_DCI : NDS_DCI_white);
else if (mode == 3.0) do_color_transformation(white_toggle == 0.0 ? NDS_Rec2020 : NDS_Rec2020_white);
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment