From 70baa386780d1d87ca0b56788a8702b771b7c671 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Mon, 29 Jun 2020 12:11:21 +0100 Subject: [PATCH] Add lcd1x shaders --- handheld/lcd1x.slangp | 10 +++ handheld/lcd1x_nds.slangp | 10 +++ handheld/lcd1x_psp.slangp | 10 +++ handheld/shaders/lcd1x.slang | 83 ++++++++++++++++++++++ handheld/shaders/lcd1x_nds.slang | 116 +++++++++++++++++++++++++++++++ handheld/shaders/lcd1x_psp.slang | 116 +++++++++++++++++++++++++++++++ 6 files changed, 345 insertions(+) create mode 100644 handheld/lcd1x.slangp create mode 100644 handheld/lcd1x_nds.slangp create mode 100644 handheld/lcd1x_psp.slangp create mode 100644 handheld/shaders/lcd1x.slang create mode 100644 handheld/shaders/lcd1x_nds.slang create mode 100644 handheld/shaders/lcd1x_psp.slang diff --git a/handheld/lcd1x.slangp b/handheld/lcd1x.slangp new file mode 100644 index 0000000..68ab4c7 --- /dev/null +++ b/handheld/lcd1x.slangp @@ -0,0 +1,10 @@ +shaders = "1" + +shader0 = "shaders/lcd1x.slang" + +filter_linear0 = "false" +wrap_mode0 = "clamp_to_border" +mipmap_input0 = "false" +alias0 = "" +float_framebuffer0 = "false" +srgb_framebuffer0 = "false" diff --git a/handheld/lcd1x_nds.slangp b/handheld/lcd1x_nds.slangp new file mode 100644 index 0000000..e5e025f --- /dev/null +++ b/handheld/lcd1x_nds.slangp @@ -0,0 +1,10 @@ +shaders = "1" + +shader0 = "shaders/lcd1x_nds.slang" + +filter_linear0 = "false" +wrap_mode0 = "clamp_to_border" +mipmap_input0 = "false" +alias0 = "" +float_framebuffer0 = "false" +srgb_framebuffer0 = "false" diff --git a/handheld/lcd1x_psp.slangp b/handheld/lcd1x_psp.slangp new file mode 100644 index 0000000..531e50b --- /dev/null +++ b/handheld/lcd1x_psp.slangp @@ -0,0 +1,10 @@ +shaders = "1" + +shader0 = "shaders/lcd1x_psp.slang" + +filter_linear0 = "false" +wrap_mode0 = "clamp_to_border" +mipmap_input0 = "false" +alias0 = "" +float_framebuffer0 = "false" +srgb_framebuffer0 = "false" diff --git a/handheld/shaders/lcd1x.slang b/handheld/shaders/lcd1x.slang new file mode 100644 index 0000000..22696d0 --- /dev/null +++ b/handheld/shaders/lcd1x.slang @@ -0,0 +1,83 @@ +#version 450 + +/* + lcd1x shader + + A slightly tweaked version of lcd3x, original code written by Gigaherz + and released into the public domain: + + > Omits LCD 'colour seperation' effect + + > Has 'properly' aligned scanlines + + Edited by jdgleaver + + 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. +*/ + +#pragma parameter BRIGHTEN_SCANLINES "Brighten Scanlines" 16.0 1.0 32.0 0.5 +#pragma parameter BRIGHTEN_LCD "Brighten LCD" 4.0 1.0 12.0 0.1 + +layout(push_constant) uniform Push +{ + float BRIGHTEN_SCANLINES; + float BRIGHTEN_LCD; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; +} registers; + +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; + +/* + VERTEX_SHADER +*/ +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; + +// Magic Numbers +#define PI 3.141592654 + +/* + FRAGMENT SHADER +*/ +void main() +{ + // Generate LCD grid effect + // > Note the 0.25 pixel offset -> required to ensure that + // scanlines occur *between* pixels + vec2 pixelCoord = vTexCoord.xy * registers.SourceSize.xy; + vec2 angle = 2.0 * PI * (pixelCoord - 0.25); + + float yfactor = (registers.BRIGHTEN_SCANLINES + sin(angle.y)) / (registers.BRIGHTEN_SCANLINES + 1.0); + float xfactor = (registers.BRIGHTEN_LCD + sin(angle.x)) / (registers.BRIGHTEN_LCD + 1.0); + + // Get colour sample + vec3 colour = texture(Source, registers.SourceSize.zw * pixelCoord.xy).rgb; + + // Apply LCD grid effect + colour.rgb = yfactor * xfactor * colour.rgb; + + FragColor = vec4(colour.rgb, 1.0); +} diff --git a/handheld/shaders/lcd1x_nds.slang b/handheld/shaders/lcd1x_nds.slang new file mode 100644 index 0000000..df592d3 --- /dev/null +++ b/handheld/shaders/lcd1x_nds.slang @@ -0,0 +1,116 @@ +#version 450 + +/* + lcd1x_nds shader + + A slightly tweaked version of lcd3x: + + - Original lcd3x code written by Gigaherz and released into the public domain + + - Original 'nds_color' code written by hunterk, modified by Pokefan531 and + released into the public domain + + Notes: + + > Omits LCD 'colour seperation' effect + + > Has 'properly' aligned scanlines + + > Includes NDS colour correction + + > Supports any NDS internal resolution setting + + Edited by jdgleaver + + 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. +*/ + +#pragma parameter BRIGHTEN_SCANLINES "Brighten Scanlines" 16.0 1.0 32.0 0.5 +#pragma parameter BRIGHTEN_LCD "Brighten LCD" 4.0 1.0 12.0 0.1 + +layout(push_constant) uniform Push +{ + float BRIGHTEN_SCANLINES; + float BRIGHTEN_LCD; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; +} registers; + +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; + +/* + VERTEX_SHADER +*/ +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; + +// Magic Numbers +#define PI 3.141592654 + +#define NDS_SCREEN_HEIGHT 192.0 + +#define TARGET_GAMMA 2.2 +const float INV_DISPLAY_GAMMA = 1.0 / 2.2; +#define CC_R 0.85 +#define CC_G 0.655 +#define CC_B 0.865 +#define CC_RG 0.095 +#define CC_RB 0.06 +#define CC_GR 0.20 +#define CC_GB 0.075 +#define CC_BR -0.05 +#define CC_BG 0.25 + +/* + FRAGMENT SHADER +*/ +void main() +{ + // Generate LCD grid effect + // > Note the 0.25 pixel offset -> required to ensure that + // scanlines occur *between* pixels + // > Divide pixel coordinate by current scale factor + // (input_video_height / nds_screen_height) + vec2 pixelCoord = vTexCoord.xy * registers.SourceSize.xy; + vec2 angle = 2.0 * PI * ((pixelCoord * NDS_SCREEN_HEIGHT * registers.SourceSize.w) - 0.25); + + float yfactor = (registers.BRIGHTEN_SCANLINES + sin(angle.y)) / (registers.BRIGHTEN_SCANLINES + 1.0); + float xfactor = (registers.BRIGHTEN_LCD + sin(angle.x)) / (registers.BRIGHTEN_LCD + 1.0); + + // Get colour sample + vec3 colour = texture(Source, registers.SourceSize.zw * pixelCoord.xy).rgb; + + // Apply colour correction + colour.rgb = pow(colour.rgb, vec3(TARGET_GAMMA)); + colour.rgb = mat3(CC_R, CC_RG, CC_RB, + CC_GR, CC_G, CC_GB, + CC_BR, CC_BG, CC_B) * colour.rgb; + colour.rgb = clamp(pow(colour.rgb, vec3(INV_DISPLAY_GAMMA)), 0.0, 1.0); + + // Apply LCD grid effect + colour.rgb = yfactor * xfactor * colour.rgb; + + FragColor = vec4(colour.rgb, 1.0); +} diff --git a/handheld/shaders/lcd1x_psp.slang b/handheld/shaders/lcd1x_psp.slang new file mode 100644 index 0000000..597cb09 --- /dev/null +++ b/handheld/shaders/lcd1x_psp.slang @@ -0,0 +1,116 @@ +#version 450 + +/* + lcd1x_psp shader + + A slightly tweaked version of lcd3x: + + - Original lcd3x code written by Gigaherz and released into the public domain + + - Original 'psp_color' code written by hunterk, modified by Pokefan531 and + released into the public domain + + Notes: + + > Omits LCD 'colour seperation' effect + + > Has 'properly' aligned scanlines + + > Includes PSP colour correction + + > Supports any PSP internal resolution setting + + Edited by jdgleaver + + 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. +*/ + +#pragma parameter BRIGHTEN_SCANLINES "Brighten Scanlines" 16.0 1.0 32.0 0.5 +#pragma parameter BRIGHTEN_LCD "Brighten LCD" 4.0 1.0 12.0 0.1 + +layout(push_constant) uniform Push +{ + float BRIGHTEN_SCANLINES; + float BRIGHTEN_LCD; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; +} registers; + +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; + +/* + VERTEX_SHADER +*/ +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; + +// Magic Numbers +#define PI 3.141592654 + +#define PSP_SCREEN_HEIGHT 272.0 + +#define TARGET_GAMMA 2.21 +const float INV_DISPLAY_GAMMA = 1.0 / 2.2; +#define CC_R 0.98 +#define CC_G 0.795 +#define CC_B 0.98 +#define CC_RG 0.04 +#define CC_RB 0.01 +#define CC_GR 0.20 +#define CC_GB 0.01 +#define CC_BR -0.18 +#define CC_BG 0.165 + +/* + FRAGMENT SHADER +*/ +void main() +{ + // Generate LCD grid effect + // > Note the 0.25 pixel offset -> required to ensure that + // scanlines occur *between* pixels + // > Divide pixel coordinate by current scale factor + // (input_video_height / psp_screen_height) + vec2 pixelCoord = vTexCoord.xy * registers.SourceSize.xy; + vec2 angle = 2.0 * PI * ((pixelCoord * PSP_SCREEN_HEIGHT * registers.SourceSize.w) - 0.25); + + float yfactor = (registers.BRIGHTEN_SCANLINES + sin(angle.y)) / (registers.BRIGHTEN_SCANLINES + 1.0); + float xfactor = (registers.BRIGHTEN_LCD + sin(angle.x)) / (registers.BRIGHTEN_LCD + 1.0); + + // Get colour sample + vec3 colour = texture(Source, registers.SourceSize.zw * pixelCoord.xy).rgb; + + // Apply colour correction + colour.rgb = pow(colour.rgb, vec3(TARGET_GAMMA)); + colour.rgb = mat3(CC_R, CC_RG, CC_RB, + CC_GR, CC_G, CC_GB, + CC_BR, CC_BG, CC_B) * colour.rgb; + colour.rgb = clamp(pow(colour.rgb, vec3(INV_DISPLAY_GAMMA)), 0.0, 1.0); + + // Apply LCD grid effect + colour.rgb = yfactor * xfactor * colour.rgb; + + FragColor = vec4(colour.rgb, 1.0); +}