diff --git a/res/shaders/gba-color.shader/gba-color.fs b/res/shaders/gba-color.shader/gba-color.fs index 09177ddfe..461228c20 100644 --- a/res/shaders/gba-color.shader/gba-color.fs +++ b/res/shaders/gba-color.shader/gba-color.fs @@ -1,34 +1,21 @@ +// Shader that replicates the LCD Colorspace from Gameboy Advance -- varying vec2 texCoord; +varying mat4 profile; uniform sampler2D tex; uniform vec2 texSize; uniform float darken_screen; -const float target_gamma = 2.2; -const float display_gamma = 2.5; -const float sat = 1.0; -const float lum = 0.99; -const float contrast = 1.0; -const vec3 bl = vec3(0.0, 0.0, 0.0); -const vec3 r = vec3(0.84, 0.09, 0.15); -const vec3 g = vec3(0.18, 0.67, 0.10); -const vec3 b = vec3(0.0, 0.26, 0.73); +const float target_gamma = 2.0; +const float display_gamma = 2.0; void main() { + // bring out our stored luminance value + float lum = profile[3].w; + + // our adjustments need to happen in linear gamma vec4 screen = pow(texture2D(tex, texCoord), vec4(target_gamma + darken_screen)).rgba; - vec4 avglum = vec4(0.5); - screen = mix(screen, avglum, (1.0 - contrast)); - - mat4 color = mat4( r.r, r.g, r.b, 0.0, - g.r, g.g, g.b, 0.0, - b.r, b.g, b.b, 0.0, - bl.r, bl.g, bl.b, 1.0); - - mat4 adjust = mat4( (1.0 - sat) * 0.3086 + sat, (1.0 - sat) * 0.3086, (1.0 - sat) * 0.3086, 1.0, - (1.0 - sat) * 0.6094, (1.0 - sat) * 0.6094 + sat, (1.0 - sat) * 0.6094, 1.0, - (1.0 - sat) * 0.0820, (1.0 - sat) * 0.0820, (1.0 - sat) * 0.0820 + sat, 1.0, - 0.0, 0.0, 0.0, 1.0); - color *= adjust; + screen = clamp(screen * lum, 0.0, 1.0); - screen = color * screen; - gl_FragColor = pow(screen, vec4(1.0 / display_gamma + (darken_screen * 0.125))); + screen = profile * screen; + gl_FragColor = pow(screen, vec4(1.0 / display_gamma)); } diff --git a/res/shaders/gba-color.shader/gba-color.vs b/res/shaders/gba-color.shader/gba-color.vs new file mode 100644 index 000000000..bbf406278 --- /dev/null +++ b/res/shaders/gba-color.shader/gba-color.vs @@ -0,0 +1,34 @@ +uniform int color_mode; +attribute vec4 position; +varying vec2 texCoord; +varying mat4 profile; + +const mat4 GBA_sRGB = mat4( + 0.80, 0.135, 0.195, 0.0, //red channel + 0.275, 0.64, 0.155, 0.0, //green channel + -0.075, 0.225, 0.65, 0.0, //blue channel + 0.0, 0.0, 0.0, 0.93 //alpha channel +); + +const mat4 GBA_DCI = mat4( + 0.685, 0.16, 0.20, 0.0, //red channel + 0.34, 0.629, 0.19, 0.0, //green channel + -0.025, 0.211, 0.61, 0.0, //blue channel + 0.0, 0.0, 0.0, 0.975 //alpha channel +); + +const mat4 GBA_Rec2020 = mat4( + 0.555, 0.1825, 0.20, 0.0, //red channel + 0.395, 0.61, 0.195, 0.0, //green channel + 0.05, 0.2075, 0.605, 0.0, //blue channel + 0.0, 0.0, 0.0, 1.0 //alpha channel +); + +void main() { + if (color_mode == 1) profile = GBA_sRGB; + else if (color_mode == 2) profile = GBA_DCI; + else if (color_mode == 3) profile = GBA_Rec2020; + + gl_Position = position; + texCoord = (position.st + vec2(1.0, 1.0)) * vec2(0.5, 0.5); +} diff --git a/res/shaders/gba-color.shader/manifest.ini b/res/shaders/gba-color.shader/manifest.ini index 8f9735aa3..ed16900cd 100644 --- a/res/shaders/gba-color.shader/manifest.ini +++ b/res/shaders/gba-color.shader/manifest.ini @@ -6,6 +6,7 @@ passes=1 [pass.0] fragmentShader=gba-color.fs +vertexShader=gba-color.vs blend=1 width=-1 height=-1 @@ -14,3 +15,10 @@ height=-1 type=float default=0.5 readableName=Darken Screen + +[pass.0.uniform.color_mode] +type=int +default=1 +min=1 +max=3 +readableName=Color Profile (1=sRGB, 2=DCI, 3=Rec2020)