├── README.md ├── bead+psp_color.fsh ├── bead+psp_color_mobile.fsh ├── bead.fsh ├── bead.ini ├── bead.vsh ├── bead_mobile.fsh ├── dot+psp_color.fsh ├── dot+psp_color_mobile.fsh ├── dot.fsh ├── dot.ini ├── dot.vsh ├── dot_mobile.fsh ├── lcd1x_sharp+psp_color.fsh ├── lcd1x_sharp+psp_color_mobile.fsh ├── lcd1x_sharp.fsh ├── lcd1x_sharp.ini ├── lcd1x_sharp.vsh ├── lcd1x_sharp_mobile.fsh ├── lcd3x+psp_color.fsh ├── lcd3x+psp_color_mobile.fsh ├── lcd3x.fsh ├── lcd3x.ini ├── lcd3x.vsh ├── lcd3x_mobile.fsh ├── psp_color.fsh ├── psp_color.ini ├── psp_color.vsh ├── psp_color_mobile.fsh ├── zfast_lcd+psp_color.fsh ├── zfast_lcd+psp_color.ini ├── zfast_lcd+psp_color_mobile.fsh ├── zfast_lcd.fsh ├── zfast_lcd.ini ├── zfast_lcd.vsh ├── zfast_lcd_hd+psp_color.fsh ├── zfast_lcd_hd+psp_color_mobile.fsh ├── zfast_lcd_hd.fsh ├── zfast_lcd_hd_mobile.fsh └── zfast_lcd_mobile.fsh /README.md: -------------------------------------------------------------------------------- 1 | # ppsspp_shaders 2 | 3 | A small collection of shaders for [PPSSPP](https://www.ppsspp.org/) standalone, ported from various sources. 4 | 5 | - All shaders include a '(Mobile)' variant which forces 'highp' variable precision for compatibility with Android devices 6 | 7 | - All shaders include a '+ PSP Color' variant, which applies colour correction to replicate the LCD dynamics of the PSP 1000 and PSP 2000 displays 8 | 9 | ## Bead 10 | 11 | A port of the 'bead' shader from RetroArch, which turns each pixel into a round bead. The native PSP resolution is too high for this to work entirely as it should (unless used with a 4k+ display), but it still produces quite a nice clean, crisp result. 12 | 13 | - REQUIRES a rendering resolution of 1xPSP 14 | 15 | - REQUIRES a display resolution of at least 1080p 16 | 17 | - Runs at full speed on mid-range Android devices 18 | 19 | ## Dot 20 | 21 | A port of the 'dot' shader from RetroArch, which produces an LCD effect with a cosy sort of glow. 22 | 23 | - REQUIRES a rendering resolution of 1xPSP 24 | 25 | - REQUIRES a display resolution of at least 1080p 26 | 27 | - This is quite a 'heavy' shader, intended for Desktop use. The '(Mobile)' version will only run at full speed on high end Android devices. 28 | 29 | ## LCD3x 30 | 31 | A port of the LCD3x shader from RetroArch. 32 | 33 | - REQUIRES a rendering resolution of 1xPSP 34 | 35 | - Runs at full speed on mid-range Android devices 36 | 37 | - Does *not* require a 1080p display. This shader produces decent results (i.e. no unbearable aliasing effects) at 1360x768, and so is appropriate for potato laptops 38 | 39 | ## LCD1x 40 | 41 | A 'tweaked' version of LCD3x that is 'sharp' and which omits the 3-band LCD colour effect. 42 | 43 | - REQUIRES a rendering resolution of 1xPSP 44 | 45 | - Runs at full speed on mid-range Android devices 46 | 47 | - Does *not* require a 1080p display. This shader produces decent results (i.e. no unbearable aliasing effects) at 1360x768, and so is appropriate for potato laptops 48 | 49 | ## PSP Color 50 | 51 | Simply applies PSP colour correction. 52 | 53 | - Works with any rendering resolution 54 | 55 | - Runs at full speed on mid-range Android devices 56 | 57 | - Has no display resolution requirements 58 | 59 | ## zfast LCD 60 | 61 | A port of the zfast_lcd shader from RetroArch. This creates an LCD effect by performing nearest neighbour scaling and adding a subtle grid lattice. 62 | 63 | - REQUIRES a rendering resolution of 1xPSP 64 | 65 | - REQUIRES a display resolution of at least 1080p 66 | 67 | - Runs at full speed on mid-range Android devices 68 | 69 | ## zfast LCD HD 70 | 71 | A tweaked version of 'zfast LCD' which supports arbitrary rendering resolutions. Applies the same grid effect, but omits the nearest neighbour scaling. 72 | 73 | - Works with any rendering resolution 74 | 75 | - REQUIRES a display resolution of at least 1080p 76 | 77 | - Runs at full speed on mid-range Android devices 78 | -------------------------------------------------------------------------------- /bead+psp_color.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | bead+psp_color fragment shader 3 | 4 | - Original 'bead' code by Themaister, released into the public domain 5 | 6 | - Original 'psp_color' code written by hunterk, modified by Pokefan531 and 7 | released into the public domain 8 | 9 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 10 | 11 | This program is free software; you can redistribute it and/or modify it 12 | under the terms of the GNU General Public License as published by the Free 13 | Software Foundation; either version 2 of the License, or (at your option) 14 | any later version. 15 | 16 | *** Requires rendering resolution to be set to 1xPSP 17 | 18 | *** Absolutely requires a display resolution of at least 1080p 19 | */ 20 | 21 | //=== Config 22 | #define BEAD_HIGH 0.35 // "Bead High" - default: 0.35, min: 0.0, max: 1.0, step: 0.01 23 | //#define BEAD_LOW 0.2 // "Bead Low" - default: 0.2, min: 0.0, max: 1.0, step: 0.01 24 | 25 | //================ 26 | #ifdef GL_ES 27 | precision mediump float; 28 | precision mediump int; 29 | // For android, use this instead... 30 | //precision highp float; 31 | //precision highp int; 32 | // 33 | #endif 34 | 35 | //================ 36 | #define target_gamma 2.21 37 | #define display_gamma 2.2 38 | #define r 0.98 39 | #define g 0.795 40 | #define b 0.98 41 | #define rg 0.04 42 | #define rb 0.01 43 | #define gr 0.20 44 | #define gb 0.01 45 | #define br -0.18 46 | #define bg 0.165 47 | 48 | //================ 49 | uniform sampler2D sampler0; 50 | uniform vec2 u_texelDelta; 51 | varying vec2 v_texcoord0; 52 | 53 | // Have to use standard names to ensure compatibility with 54 | // Vulkan backend... 55 | varying vec2 v_texcoord1; // pixel_no 56 | 57 | //================ 58 | float dist(vec2 coord, vec2 source) 59 | { 60 | vec2 delta = coord - source; 61 | return sqrt(dot(delta, delta)); 62 | } 63 | 64 | float rolloff(float len) 65 | { 66 | return exp(-6.0 * len); 67 | } 68 | 69 | vec3 lookup(vec2 pixel_no, vec3 color) 70 | { 71 | float delta = dist(fract(pixel_no), vec2(0.5, 0.5)); 72 | 73 | // if (delta > BEAD_LOW && delta < BEAD_HIGH) 74 | // return color; 75 | // else if (delta >= BEAD_HIGH) 76 | // return color * rolloff(delta - BEAD_HIGH); 77 | // else if (delta <= BEAD_LOW) 78 | // return color * rolloff(BEAD_LOW - delta); 79 | // else 80 | // return vec3(0.0, 0.0, 0.0); 81 | 82 | // The PSP has such a 'high' resolution that the 83 | // 'hole' in the bead will never be visible on any 84 | // conventional display. We can therefore reduce the 85 | // performance impact of this shader by ignoring the 86 | // 'BEAD_LOW' stuff 87 | if (delta < BEAD_HIGH) 88 | return color; 89 | else 90 | return color * rolloff(delta - BEAD_HIGH); 91 | } 92 | 93 | //================ 94 | void main() 95 | { 96 | // Get colour sample and apply colour correction 97 | vec3 mid_color = pow( 98 | lookup(v_texcoord1, texture2D(sampler0, v_texcoord0.xy).rgb), // pixel_no == v_texcoord1 99 | vec3(target_gamma) 100 | ); 101 | mid_color = clamp(mid_color, 0.0, 1.0); 102 | mid_color = pow( 103 | mat3(r, rg, rb, 104 | gr, g, gb, 105 | br, bg, b) * mid_color, 106 | vec3(1.0 / display_gamma) 107 | ); 108 | 109 | gl_FragColor = vec4(mid_color, 1.0); 110 | } 111 | -------------------------------------------------------------------------------- /bead+psp_color_mobile.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | bead+psp_color fragment shader 3 | 4 | - Original 'bead' code by Themaister, released into the public domain 5 | 6 | - Original 'psp_color' code written by hunterk, modified by Pokefan531 and 7 | released into the public domain 8 | 9 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 10 | 11 | This program is free software; you can redistribute it and/or modify it 12 | under the terms of the GNU General Public License as published by the Free 13 | Software Foundation; either version 2 of the License, or (at your option) 14 | any later version. 15 | 16 | *** Requires rendering resolution to be set to 1xPSP 17 | 18 | *** Absolutely requires a display resolution of at least 1080p 19 | */ 20 | 21 | //=== Config 22 | #define BEAD_HIGH 0.35 // "Bead High" - default: 0.35, min: 0.0, max: 1.0, step: 0.01 23 | //#define BEAD_LOW 0.2 // "Bead Low" - default: 0.2, min: 0.0, max: 1.0, step: 0.01 24 | 25 | //================ 26 | #ifdef GL_ES 27 | //precision mediump float; 28 | //precision mediump int; 29 | // For android, use this instead... 30 | precision highp float; 31 | precision highp int; 32 | #endif 33 | 34 | //================ 35 | #define target_gamma 2.21 36 | #define display_gamma 2.2 37 | #define r 0.98 38 | #define g 0.795 39 | #define b 0.98 40 | #define rg 0.04 41 | #define rb 0.01 42 | #define gr 0.20 43 | #define gb 0.01 44 | #define br -0.18 45 | #define bg 0.165 46 | 47 | //================ 48 | uniform sampler2D sampler0; 49 | uniform vec2 u_texelDelta; 50 | varying vec2 v_texcoord0; 51 | 52 | // Have to use standard names to ensure compatibility with 53 | // Vulkan backend... 54 | varying vec2 v_texcoord1; // pixel_no 55 | 56 | //================ 57 | float dist(vec2 coord, vec2 source) 58 | { 59 | vec2 delta = coord - source; 60 | return sqrt(dot(delta, delta)); 61 | } 62 | 63 | float rolloff(float len) 64 | { 65 | return exp(-6.0 * len); 66 | } 67 | 68 | vec3 lookup(vec2 pixel_no, vec3 color) 69 | { 70 | float delta = dist(fract(pixel_no), vec2(0.5, 0.5)); 71 | 72 | // if (delta > BEAD_LOW && delta < BEAD_HIGH) 73 | // return color; 74 | // else if (delta >= BEAD_HIGH) 75 | // return color * rolloff(delta - BEAD_HIGH); 76 | // else if (delta <= BEAD_LOW) 77 | // return color * rolloff(BEAD_LOW - delta); 78 | // else 79 | // return vec3(0.0, 0.0, 0.0); 80 | 81 | // The PSP has such a 'high' resolution that the 82 | // 'hole' in the bead will never be visible on any 83 | // conventional display. We can therefore reduce the 84 | // performance impact of this shader by ignoring the 85 | // 'BEAD_LOW' stuff 86 | if (delta < BEAD_HIGH) 87 | return color; 88 | else 89 | return color * rolloff(delta - BEAD_HIGH); 90 | } 91 | 92 | //================ 93 | void main() 94 | { 95 | // Get colour sample and apply colour correction 96 | vec3 mid_color = pow( 97 | lookup(v_texcoord1, texture2D(sampler0, v_texcoord0.xy).rgb), // pixel_no == v_texcoord1 98 | vec3(target_gamma) 99 | ); 100 | mid_color = clamp(mid_color, 0.0, 1.0); 101 | mid_color = pow( 102 | mat3(r, rg, rb, 103 | gr, g, gb, 104 | br, bg, b) * mid_color, 105 | vec3(1.0 / display_gamma) 106 | ); 107 | 108 | gl_FragColor = vec4(mid_color, 1.0); 109 | } 110 | -------------------------------------------------------------------------------- /bead.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | bead fragment shader 3 | 4 | Original code by Themaister, released into the public domain 5 | 6 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 7 | 8 | This program is free software; you can redistribute it and/or modify it 9 | under the terms of the GNU General Public License as published by the Free 10 | Software Foundation; either version 2 of the License, or (at your option) 11 | any later version. 12 | 13 | *** Requires rendering resolution to be set to 1xPSP 14 | 15 | *** Absolutely requires a display resolution of at least 1080p 16 | */ 17 | 18 | //=== Config 19 | #define BEAD_HIGH 0.35 // "Bead High" - default: 0.35, min: 0.0, max: 1.0, step: 0.01 20 | //#define BEAD_LOW 0.2 // "Bead Low" - default: 0.2, min: 0.0, max: 1.0, step: 0.01 21 | 22 | //================ 23 | #ifdef GL_ES 24 | precision mediump float; 25 | precision mediump int; 26 | // For android, use this instead... 27 | //precision highp float; 28 | //precision highp int; 29 | // 30 | #endif 31 | 32 | //================ 33 | uniform sampler2D sampler0; 34 | uniform vec2 u_texelDelta; 35 | varying vec2 v_texcoord0; 36 | 37 | // Have to use standard names to ensure compatibility with 38 | // Vulkan backend... 39 | varying vec2 v_texcoord1; // pixel_no 40 | 41 | //================ 42 | float dist(vec2 coord, vec2 source) 43 | { 44 | vec2 delta = coord - source; 45 | return sqrt(dot(delta, delta)); 46 | } 47 | 48 | float rolloff(float len) 49 | { 50 | return exp(-6.0 * len); 51 | } 52 | 53 | vec3 lookup(vec2 pixel_no, vec3 color) 54 | { 55 | float delta = dist(fract(pixel_no), vec2(0.5, 0.5)); 56 | 57 | // if (delta > BEAD_LOW && delta < BEAD_HIGH) 58 | // return color; 59 | // else if (delta >= BEAD_HIGH) 60 | // return color * rolloff(delta - BEAD_HIGH); 61 | // else if (delta <= BEAD_LOW) 62 | // return color * rolloff(BEAD_LOW - delta); 63 | // else 64 | // return vec3(0.0, 0.0, 0.0); 65 | 66 | // The PSP has such a 'high' resolution that the 67 | // 'hole' in the bead will never be visible on any 68 | // conventional display. We can therefore reduce the 69 | // performance impact of this shader by ignoring the 70 | // 'BEAD_LOW' stuff 71 | if (delta < BEAD_HIGH) 72 | return color; 73 | else 74 | return color * rolloff(delta - BEAD_HIGH); 75 | } 76 | 77 | //================ 78 | void main() 79 | { 80 | vec3 mid_color = lookup(v_texcoord1, texture2D(sampler0, v_texcoord0.xy).rgb); // pixel_no == v_texcoord1 81 | 82 | gl_FragColor = vec4(mid_color, 1.0); 83 | } 84 | -------------------------------------------------------------------------------- /bead.ini: -------------------------------------------------------------------------------- 1 | [Bead] 2 | Name=Bead 3 | Author=Themaister, ported by jdgleaver 4 | Fragment=bead.fsh 5 | Vertex=bead.vsh 6 | OutputResolution=True 7 | Upscaling=True 8 | [Bead (Mobile)] 9 | Name=Bead (Mobile) 10 | Author=Themaister, ported by jdgleaver 11 | Fragment=bead_mobile.fsh 12 | Vertex=bead.vsh 13 | OutputResolution=True 14 | Upscaling=True 15 | [Bead + PSP Color] 16 | Name=Bead + PSP Color 17 | Author=Themaister, hunterk, Pokefan531, ported by jdgleaver 18 | Fragment=bead+psp_color.fsh 19 | Vertex=bead.vsh 20 | OutputResolution=True 21 | Upscaling=True 22 | [Bead + PSP Color (Mobile)] 23 | Name=Bead + PSP Color (Mobile) 24 | Author=Themaister, hunterk, Pokefan531, ported by jdgleaver 25 | Fragment=bead+psp_color_mobile.fsh 26 | Vertex=bead.vsh 27 | OutputResolution=True 28 | Upscaling=True 29 | -------------------------------------------------------------------------------- /bead.vsh: -------------------------------------------------------------------------------- 1 | /* 2 | bead fragment shader 3 | 4 | Original code by Themaister, released into the public domain 5 | 6 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 7 | 8 | This program is free software; you can redistribute it and/or modify it 9 | under the terms of the GNU General Public License as published by the Free 10 | Software Foundation; either version 2 of the License, or (at your option) 11 | any later version. 12 | 13 | *** Requires rendering resolution to be set to 1xPSP 14 | 15 | *** Absolutely requires a display resolution of at least 1080p 16 | */ 17 | 18 | uniform vec2 u_texelDelta; 19 | attribute vec4 a_position; 20 | attribute vec2 a_texcoord0; 21 | varying vec2 v_texcoord0; 22 | 23 | // Have to use standard names to ensure compatibility with 24 | // Vulkan backend... 25 | varying vec2 v_texcoord1; // pixel_no 26 | 27 | void main() 28 | { 29 | v_texcoord0 = a_texcoord0; 30 | gl_Position = a_position; 31 | v_texcoord1 = v_texcoord0 * (1.0 / u_texelDelta.xy); // pixel_no 32 | } 33 | -------------------------------------------------------------------------------- /bead_mobile.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | bead fragment shader 3 | 4 | Original code by Themaister, released into the public domain 5 | 6 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 7 | 8 | This program is free software; you can redistribute it and/or modify it 9 | under the terms of the GNU General Public License as published by the Free 10 | Software Foundation; either version 2 of the License, or (at your option) 11 | any later version. 12 | 13 | *** Requires rendering resolution to be set to 1xPSP 14 | 15 | *** Absolutely requires a display resolution of at least 1080p 16 | */ 17 | 18 | //=== Config 19 | #define BEAD_HIGH 0.35 // "Bead High" - default: 0.35, min: 0.0, max: 1.0, step: 0.01 20 | //#define BEAD_LOW 0.2 // "Bead Low" - default: 0.2, min: 0.0, max: 1.0, step: 0.01 21 | 22 | //================ 23 | #ifdef GL_ES 24 | //precision mediump float; 25 | //precision mediump int; 26 | // For android, use this instead... 27 | precision highp float; 28 | precision highp int; 29 | #endif 30 | 31 | //================ 32 | uniform sampler2D sampler0; 33 | uniform vec2 u_texelDelta; 34 | varying vec2 v_texcoord0; 35 | 36 | // Have to use standard names to ensure compatibility with 37 | // Vulkan backend... 38 | varying vec2 v_texcoord1; // pixel_no 39 | 40 | //================ 41 | float dist(vec2 coord, vec2 source) 42 | { 43 | vec2 delta = coord - source; 44 | return sqrt(dot(delta, delta)); 45 | } 46 | 47 | float rolloff(float len) 48 | { 49 | return exp(-6.0 * len); 50 | } 51 | 52 | vec3 lookup(vec2 pixel_no, vec3 color) 53 | { 54 | float delta = dist(fract(pixel_no), vec2(0.5, 0.5)); 55 | 56 | // if (delta > BEAD_LOW && delta < BEAD_HIGH) 57 | // return color; 58 | // else if (delta >= BEAD_HIGH) 59 | // return color * rolloff(delta - BEAD_HIGH); 60 | // else if (delta <= BEAD_LOW) 61 | // return color * rolloff(BEAD_LOW - delta); 62 | // else 63 | // return vec3(0.0, 0.0, 0.0); 64 | 65 | // The PSP has such a 'high' resolution that the 66 | // 'hole' in the bead will never be visible on any 67 | // conventional display. We can therefore reduce the 68 | // performance impact of this shader by ignoring the 69 | // 'BEAD_LOW' stuff 70 | if (delta < BEAD_HIGH) 71 | return color; 72 | else 73 | return color * rolloff(delta - BEAD_HIGH); 74 | } 75 | 76 | //================ 77 | void main() 78 | { 79 | vec3 mid_color = lookup(v_texcoord1, texture2D(sampler0, v_texcoord0.xy).rgb); // pixel_no == v_texcoord1 80 | 81 | gl_FragColor = vec4(mid_color, 1.0); 82 | } 83 | -------------------------------------------------------------------------------- /dot+psp_color.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | dot+psp_color fragment shader 3 | 4 | - Original 'dot' code by Themaister, released into the public domain 5 | 6 | - Original 'psp_color' code written by hunterk, modified by Pokefan531 and 7 | released into the public domain 8 | 9 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 10 | 11 | This program is free software; you can redistribute it and/or modify it 12 | under the terms of the GNU General Public License as published by the Free 13 | Software Foundation; either version 2 of the License, or (at your option) 14 | any later version. 15 | */ 16 | 17 | //=== Config 18 | #define gamma 2.4 // "Dot Gamma" - default: 2.4, min: 0.0, max: 5.0, step: 0.05 19 | #define shine 0.05 // "Dot Shine" - default: 0.05, min: 0.0, max: 0.5, step: 0.01 20 | #define blend 0.65 // "Dot Blend" - default: 0.65, min: 0.0, max: 1.0, step: 0.01 21 | 22 | //================ 23 | #ifdef GL_ES 24 | precision mediump float; 25 | precision mediump int; 26 | // For android, use this instead... 27 | //precision highp float; 28 | //precision highp int; 29 | // 30 | #endif 31 | 32 | //================ 33 | #define target_gamma 2.21 34 | #define display_gamma 2.2 35 | #define r 0.98 36 | #define g 0.795 37 | #define b 0.98 38 | #define rg 0.04 39 | #define rb 0.01 40 | #define gr 0.20 41 | #define gb 0.01 42 | #define br -0.18 43 | #define bg 0.165 44 | 45 | //================ 46 | uniform sampler2D sampler0; 47 | uniform vec2 u_texelDelta; 48 | varying vec2 v_texcoord0; 49 | 50 | // OK - brace yourselves! This is going to get ugly... 51 | // In order for this to work with the Vukan backend, we can only use 52 | // variables with specific names (determined by the automated shader 53 | // translation). So everything gets called v_texcoord... 54 | varying vec4 v_texcoord1; // c00_10 55 | varying vec4 v_texcoord2; // c20_01 56 | varying vec4 v_texcoord3; // c21_02 57 | varying vec4 v_texcoord4; // c12_22 58 | varying vec2 v_texcoord5; // c11 59 | varying vec2 v_texcoord6; // pixel_no 60 | 61 | //================ 62 | float dist(vec2 coord, vec2 source) 63 | { 64 | vec2 delta = coord - source; 65 | return sqrt(dot(delta, delta)); 66 | } 67 | 68 | float color_bloom(vec3 color) 69 | { 70 | const vec3 gray_coeff = vec3(0.30, 0.59, 0.11); 71 | float bright = dot(color, gray_coeff); 72 | return mix(1.0 + shine, 1.0 - shine, bright); 73 | } 74 | 75 | vec3 lookup(vec2 pixel_no, float offset_x, float offset_y, vec3 color) 76 | { 77 | vec2 offset = vec2(offset_x, offset_y); 78 | float delta = dist(fract(pixel_no), offset + vec2(0.5, 0.5)); 79 | return color * exp(-gamma * delta * color_bloom(color)); 80 | } 81 | 82 | //================ 83 | void main() 84 | { 85 | // pixel_no == v_texcoord6 86 | vec3 mid_color = lookup(v_texcoord6, 0.0, 0.0, texture2D(sampler0, v_texcoord5).rgb); // c11 87 | 88 | vec3 color = vec3(0.0, 0.0, 0.0); 89 | 90 | color += lookup(v_texcoord6, -1.0, -1.0, texture2D(sampler0, v_texcoord1.xy).rgb); // c00_10 91 | color += lookup(v_texcoord6, 0.0, -1.0, texture2D(sampler0, v_texcoord1.zw).rgb); // c00_10 92 | color += lookup(v_texcoord6, 1.0, -1.0, texture2D(sampler0, v_texcoord2.xy).rgb); // c20_01 93 | color += lookup(v_texcoord6, -1.0, 0.0, texture2D(sampler0, v_texcoord2.zw).rgb); // c20_01 94 | color += mid_color; 95 | color += lookup(v_texcoord6, 1.0, 0.0, texture2D(sampler0, v_texcoord3.xy).rgb); // c21_02 96 | color += lookup(v_texcoord6, -1.0, 1.0, texture2D(sampler0, v_texcoord3.zw).rgb); // c21_02 97 | color += lookup(v_texcoord6, 0.0, 1.0, texture2D(sampler0, v_texcoord4.xy).rgb); // c12_22 98 | color += lookup(v_texcoord6, 1.0, 1.0, texture2D(sampler0, v_texcoord4.zw).rgb); // c12_22 99 | 100 | // Apply colour correction 101 | // > This is not quite right, but should be good enough... 102 | vec3 out_color = pow(mix(1.2 * mid_color, color, blend), vec3(target_gamma)); 103 | out_color = clamp(out_color, 0.0, 1.0); 104 | out_color = pow( 105 | mat3(r, rg, rb, 106 | gr, g, gb, 107 | br, bg, b) * out_color, 108 | vec3(1.0 / display_gamma) 109 | ); 110 | 111 | gl_FragColor = vec4(out_color, 1.0); 112 | } 113 | -------------------------------------------------------------------------------- /dot+psp_color_mobile.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | dot+psp_color fragment shader 3 | 4 | - Original 'dot' code by Themaister, released into the public domain 5 | 6 | - Original 'psp_color' code written by hunterk, modified by Pokefan531 and 7 | released into the public domain 8 | 9 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 10 | 11 | This program is free software; you can redistribute it and/or modify it 12 | under the terms of the GNU General Public License as published by the Free 13 | Software Foundation; either version 2 of the License, or (at your option) 14 | any later version. 15 | */ 16 | 17 | //=== Config 18 | #define gamma 2.4 // "Dot Gamma" - default: 2.4, min: 0.0, max: 5.0, step: 0.05 19 | #define shine 0.05 // "Dot Shine" - default: 0.05, min: 0.0, max: 0.5, step: 0.01 20 | #define blend 0.65 // "Dot Blend" - default: 0.65, min: 0.0, max: 1.0, step: 0.01 21 | 22 | //================ 23 | #ifdef GL_ES 24 | //precision mediump float; 25 | //precision mediump int; 26 | // For android, use this instead... 27 | precision highp float; 28 | precision highp int; 29 | #endif 30 | 31 | //================ 32 | #define target_gamma 2.21 33 | #define display_gamma 2.2 34 | #define r 0.98 35 | #define g 0.795 36 | #define b 0.98 37 | #define rg 0.04 38 | #define rb 0.01 39 | #define gr 0.20 40 | #define gb 0.01 41 | #define br -0.18 42 | #define bg 0.165 43 | 44 | //================ 45 | uniform sampler2D sampler0; 46 | uniform vec2 u_texelDelta; 47 | varying vec2 v_texcoord0; 48 | 49 | // OK - brace yourselves! This is going to get ugly... 50 | // In order for this to work with the Vukan backend, we can only use 51 | // variables with specific names (determined by the automated shader 52 | // translation). So everything gets called v_texcoord... 53 | varying vec4 v_texcoord1; // c00_10 54 | varying vec4 v_texcoord2; // c20_01 55 | varying vec4 v_texcoord3; // c21_02 56 | varying vec4 v_texcoord4; // c12_22 57 | varying vec2 v_texcoord5; // c11 58 | varying vec2 v_texcoord6; // pixel_no 59 | 60 | //================ 61 | float dist(vec2 coord, vec2 source) 62 | { 63 | vec2 delta = coord - source; 64 | return sqrt(dot(delta, delta)); 65 | } 66 | 67 | float color_bloom(vec3 color) 68 | { 69 | const vec3 gray_coeff = vec3(0.30, 0.59, 0.11); 70 | float bright = dot(color, gray_coeff); 71 | return mix(1.0 + shine, 1.0 - shine, bright); 72 | } 73 | 74 | vec3 lookup(vec2 pixel_no, float offset_x, float offset_y, vec3 color) 75 | { 76 | vec2 offset = vec2(offset_x, offset_y); 77 | float delta = dist(fract(pixel_no), offset + vec2(0.5, 0.5)); 78 | return color * exp(-gamma * delta * color_bloom(color)); 79 | } 80 | 81 | //================ 82 | void main() 83 | { 84 | // pixel_no == v_texcoord6 85 | vec3 mid_color = lookup(v_texcoord6, 0.0, 0.0, texture2D(sampler0, v_texcoord5).rgb); // c11 86 | 87 | vec3 color = vec3(0.0, 0.0, 0.0); 88 | 89 | color += lookup(v_texcoord6, -1.0, -1.0, texture2D(sampler0, v_texcoord1.xy).rgb); // c00_10 90 | color += lookup(v_texcoord6, 0.0, -1.0, texture2D(sampler0, v_texcoord1.zw).rgb); // c00_10 91 | color += lookup(v_texcoord6, 1.0, -1.0, texture2D(sampler0, v_texcoord2.xy).rgb); // c20_01 92 | color += lookup(v_texcoord6, -1.0, 0.0, texture2D(sampler0, v_texcoord2.zw).rgb); // c20_01 93 | color += mid_color; 94 | color += lookup(v_texcoord6, 1.0, 0.0, texture2D(sampler0, v_texcoord3.xy).rgb); // c21_02 95 | color += lookup(v_texcoord6, -1.0, 1.0, texture2D(sampler0, v_texcoord3.zw).rgb); // c21_02 96 | color += lookup(v_texcoord6, 0.0, 1.0, texture2D(sampler0, v_texcoord4.xy).rgb); // c12_22 97 | color += lookup(v_texcoord6, 1.0, 1.0, texture2D(sampler0, v_texcoord4.zw).rgb); // c12_22 98 | 99 | // Apply colour correction 100 | // > This is not quite right, but should be good enough... 101 | vec3 out_color = pow(mix(1.2 * mid_color, color, blend), vec3(target_gamma)); 102 | out_color = clamp(out_color, 0.0, 1.0); 103 | out_color = pow( 104 | mat3(r, rg, rb, 105 | gr, g, gb, 106 | br, bg, b) * out_color, 107 | vec3(1.0 / display_gamma) 108 | ); 109 | 110 | gl_FragColor = vec4(out_color, 1.0); 111 | } 112 | -------------------------------------------------------------------------------- /dot.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | dot fragment shader 3 | 4 | Original code by Themaister, released into the public domain 5 | 6 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 7 | 8 | This program is free software; you can redistribute it and/or modify it 9 | under the terms of the GNU General Public License as published by the Free 10 | Software Foundation; either version 2 of the License, or (at your option) 11 | any later version. 12 | */ 13 | 14 | //=== Config 15 | #define gamma 2.4 // "Dot Gamma" - default: 2.4, min: 0.0, max: 5.0, step: 0.05 16 | #define shine 0.05 // "Dot Shine" - default: 0.05, min: 0.0, max: 0.5, step: 0.01 17 | #define blend 0.65 // "Dot Blend" - default: 0.65, min: 0.0, max: 1.0, step: 0.01 18 | 19 | //================ 20 | #ifdef GL_ES 21 | precision mediump float; 22 | precision mediump int; 23 | // For android, use this instead... 24 | //precision highp float; 25 | //precision highp int; 26 | // 27 | #endif 28 | 29 | //================ 30 | uniform sampler2D sampler0; 31 | uniform vec2 u_texelDelta; 32 | varying vec2 v_texcoord0; 33 | 34 | // OK - brace yourselves! This is going to get ugly... 35 | // In order for this to work with the Vukan backend, we can only use 36 | // variables with specific names (determined by the automated shader 37 | // translation). So everything gets called v_texcoord... 38 | varying vec4 v_texcoord1; // c00_10 39 | varying vec4 v_texcoord2; // c20_01 40 | varying vec4 v_texcoord3; // c21_02 41 | varying vec4 v_texcoord4; // c12_22 42 | varying vec2 v_texcoord5; // c11 43 | varying vec2 v_texcoord6; // pixel_no 44 | 45 | //================ 46 | float dist(vec2 coord, vec2 source) 47 | { 48 | vec2 delta = coord - source; 49 | return sqrt(dot(delta, delta)); 50 | } 51 | 52 | float color_bloom(vec3 color) 53 | { 54 | const vec3 gray_coeff = vec3(0.30, 0.59, 0.11); 55 | float bright = dot(color, gray_coeff); 56 | return mix(1.0 + shine, 1.0 - shine, bright); 57 | } 58 | 59 | vec3 lookup(vec2 pixel_no, float offset_x, float offset_y, vec3 color) 60 | { 61 | vec2 offset = vec2(offset_x, offset_y); 62 | float delta = dist(fract(pixel_no), offset + vec2(0.5, 0.5)); 63 | return color * exp(-gamma * delta * color_bloom(color)); 64 | } 65 | 66 | //================ 67 | void main() 68 | { 69 | // pixel_no == v_texcoord6 70 | vec3 mid_color = lookup(v_texcoord6, 0.0, 0.0, texture2D(sampler0, v_texcoord5).rgb); // c11 71 | 72 | vec3 color = vec3(0.0, 0.0, 0.0); 73 | 74 | color += lookup(v_texcoord6, -1.0, -1.0, texture2D(sampler0, v_texcoord1.xy).rgb); // c00_10 75 | color += lookup(v_texcoord6, 0.0, -1.0, texture2D(sampler0, v_texcoord1.zw).rgb); // c00_10 76 | color += lookup(v_texcoord6, 1.0, -1.0, texture2D(sampler0, v_texcoord2.xy).rgb); // c20_01 77 | color += lookup(v_texcoord6, -1.0, 0.0, texture2D(sampler0, v_texcoord2.zw).rgb); // c20_01 78 | color += mid_color; 79 | color += lookup(v_texcoord6, 1.0, 0.0, texture2D(sampler0, v_texcoord3.xy).rgb); // c21_02 80 | color += lookup(v_texcoord6, -1.0, 1.0, texture2D(sampler0, v_texcoord3.zw).rgb); // c21_02 81 | color += lookup(v_texcoord6, 0.0, 1.0, texture2D(sampler0, v_texcoord4.xy).rgb); // c12_22 82 | color += lookup(v_texcoord6, 1.0, 1.0, texture2D(sampler0, v_texcoord4.zw).rgb); // c12_22 83 | 84 | vec3 out_color = mix(1.2 * mid_color, color, blend); 85 | 86 | gl_FragColor = vec4(out_color, 1.0); 87 | } 88 | -------------------------------------------------------------------------------- /dot.ini: -------------------------------------------------------------------------------- 1 | [Dot] 2 | Name=Dot 3 | Author=Themaister, ported by jdgleaver 4 | Fragment=dot.fsh 5 | Vertex=dot.vsh 6 | OutputResolution=True 7 | Upscaling=True 8 | [Dot (Mobile)] 9 | Name=Dot (Mobile) 10 | Author=Themaister, ported by jdgleaver 11 | Fragment=dot_mobile.fsh 12 | Vertex=dot.vsh 13 | OutputResolution=True 14 | Upscaling=True 15 | [Dot + PSP Color] 16 | Name=Dot + PSP Color 17 | Author=Themaister, hunterk, Pokefan531, ported by jdgleaver 18 | Fragment=dot+psp_color.fsh 19 | Vertex=dot.vsh 20 | OutputResolution=True 21 | Upscaling=True 22 | [Dot + PSP Color (Mobile)] 23 | Name=Dot + PSP Color (Mobile) 24 | Author=Themaister, hunterk, Pokefan531, ported by jdgleaver 25 | Fragment=dot+psp_color_mobile.fsh 26 | Vertex=dot.vsh 27 | OutputResolution=True 28 | Upscaling=True 29 | -------------------------------------------------------------------------------- /dot.vsh: -------------------------------------------------------------------------------- 1 | /* 2 | dot vertex shader 3 | 4 | Original code by Themaister, released into the public domain 5 | 6 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 7 | 8 | This program is free software; you can redistribute it and/or modify it 9 | under the terms of the GNU General Public License as published by the Free 10 | Software Foundation; either version 2 of the License, or (at your option) 11 | any later version. 12 | */ 13 | 14 | uniform vec2 u_texelDelta; 15 | attribute vec4 a_position; 16 | attribute vec2 a_texcoord0; 17 | varying vec2 v_texcoord0; 18 | 19 | // OK - brace yourselves! This is going to get ugly... 20 | // In order for this to work with the Vukan backend, we can only use 21 | // variables with specific names (determined by the automated shader 22 | // translation). So everything gets called v_texcoord... 23 | varying vec4 v_texcoord1; // c00_10 24 | varying vec4 v_texcoord2; // c20_01 25 | varying vec4 v_texcoord3; // c21_02 26 | varying vec4 v_texcoord4; // c12_22 27 | varying vec2 v_texcoord5; // c11 28 | varying vec2 v_texcoord6; // pixel_no 29 | 30 | void main() 31 | { 32 | v_texcoord0 = a_texcoord0; 33 | gl_Position = a_position; 34 | 35 | float dx = u_texelDelta.x; 36 | float dy = u_texelDelta.y; 37 | 38 | // c00_10 39 | v_texcoord1 = vec4(v_texcoord0 + vec2(-dx, -dy), v_texcoord0 + vec2(0.0, -dy)); 40 | 41 | // c20_01 42 | v_texcoord2 = vec4(v_texcoord0 + vec2(dx, -dy), v_texcoord0 + vec2(-dx, 0.0)); 43 | 44 | // c21_02 45 | v_texcoord3 = vec4(v_texcoord0 + vec2(dx, 0.0), v_texcoord0 + vec2(-dx, dy)); 46 | 47 | // c12_22 48 | v_texcoord4 = vec4(v_texcoord0 + vec2(0.0, dy), v_texcoord0 + vec2(dx, dy)); 49 | 50 | // c11 51 | v_texcoord5 = v_texcoord0; 52 | 53 | // pixel_no 54 | v_texcoord6 = v_texcoord0 * (1.0 / u_texelDelta.xy); 55 | } 56 | -------------------------------------------------------------------------------- /dot_mobile.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | dot fragment shader 3 | 4 | Original code by Themaister, released into the public domain 5 | 6 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 7 | 8 | This program is free software; you can redistribute it and/or modify it 9 | under the terms of the GNU General Public License as published by the Free 10 | Software Foundation; either version 2 of the License, or (at your option) 11 | any later version. 12 | */ 13 | 14 | //=== Config 15 | #define gamma 2.4 // "Dot Gamma" - default: 2.4, min: 0.0, max: 5.0, step: 0.05 16 | #define shine 0.05 // "Dot Shine" - default: 0.05, min: 0.0, max: 0.5, step: 0.01 17 | #define blend 0.65 // "Dot Blend" - default: 0.65, min: 0.0, max: 1.0, step: 0.01 18 | 19 | //================ 20 | #ifdef GL_ES 21 | //precision mediump float; 22 | //precision mediump int; 23 | // For android, use this instead... 24 | precision highp float; 25 | precision highp int; 26 | #endif 27 | 28 | //================ 29 | uniform sampler2D sampler0; 30 | uniform vec2 u_texelDelta; 31 | varying vec2 v_texcoord0; 32 | 33 | // OK - brace yourselves! This is going to get ugly... 34 | // In order for this to work with the Vukan backend, we can only use 35 | // variables with specific names (determined by the automated shader 36 | // translation). So everything gets called v_texcoord... 37 | varying vec4 v_texcoord1; // c00_10 38 | varying vec4 v_texcoord2; // c20_01 39 | varying vec4 v_texcoord3; // c21_02 40 | varying vec4 v_texcoord4; // c12_22 41 | varying vec2 v_texcoord5; // c11 42 | varying vec2 v_texcoord6; // pixel_no 43 | 44 | //================ 45 | float dist(vec2 coord, vec2 source) 46 | { 47 | vec2 delta = coord - source; 48 | return sqrt(dot(delta, delta)); 49 | } 50 | 51 | float color_bloom(vec3 color) 52 | { 53 | const vec3 gray_coeff = vec3(0.30, 0.59, 0.11); 54 | float bright = dot(color, gray_coeff); 55 | return mix(1.0 + shine, 1.0 - shine, bright); 56 | } 57 | 58 | vec3 lookup(vec2 pixel_no, float offset_x, float offset_y, vec3 color) 59 | { 60 | vec2 offset = vec2(offset_x, offset_y); 61 | float delta = dist(fract(pixel_no), offset + vec2(0.5, 0.5)); 62 | return color * exp(-gamma * delta * color_bloom(color)); 63 | } 64 | 65 | //================ 66 | void main() 67 | { 68 | // pixel_no == v_texcoord6 69 | vec3 mid_color = lookup(v_texcoord6, 0.0, 0.0, texture2D(sampler0, v_texcoord5).rgb); // c11 70 | 71 | vec3 color = vec3(0.0, 0.0, 0.0); 72 | 73 | color += lookup(v_texcoord6, -1.0, -1.0, texture2D(sampler0, v_texcoord1.xy).rgb); // c00_10 74 | color += lookup(v_texcoord6, 0.0, -1.0, texture2D(sampler0, v_texcoord1.zw).rgb); // c00_10 75 | color += lookup(v_texcoord6, 1.0, -1.0, texture2D(sampler0, v_texcoord2.xy).rgb); // c20_01 76 | color += lookup(v_texcoord6, -1.0, 0.0, texture2D(sampler0, v_texcoord2.zw).rgb); // c20_01 77 | color += mid_color; 78 | color += lookup(v_texcoord6, 1.0, 0.0, texture2D(sampler0, v_texcoord3.xy).rgb); // c21_02 79 | color += lookup(v_texcoord6, -1.0, 1.0, texture2D(sampler0, v_texcoord3.zw).rgb); // c21_02 80 | color += lookup(v_texcoord6, 0.0, 1.0, texture2D(sampler0, v_texcoord4.xy).rgb); // c12_22 81 | color += lookup(v_texcoord6, 1.0, 1.0, texture2D(sampler0, v_texcoord4.zw).rgb); // c12_22 82 | 83 | vec3 out_color = mix(1.2 * mid_color, color, blend); 84 | 85 | gl_FragColor = vec4(out_color, 1.0); 86 | } 87 | -------------------------------------------------------------------------------- /lcd1x_sharp+psp_color.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | lcd1x_sharp+psp_color shader 3 | 4 | This is an attempt to make a shader with a non-blurry LCD effect. 5 | It combines the existing shader code: 6 | 7 | - Nearest neighbour scaling, taken from zfast_lcd 8 | [Original code copyright (C) 2017 Greg Hogan (SoltanGris42)] 9 | 10 | - lcd3x 'grille effect', but without colour seperation 11 | [Original code by Gigaherz, released into the public domain] 12 | [Code here derived from PPSSPP version of lcd3x made by LunaMoo] 13 | 14 | - psp colour correction 15 | [Original code written by hunterk, modified by Pokefan531 and 16 | released into the public domain] 17 | 18 | Code mashed together by jdgleaver... 19 | 20 | This program is free software; you can redistribute it and/or modify it 21 | under the terms of the GNU General Public License as published by the Free 22 | Software Foundation; either version 2 of the License, or (at your option) 23 | any later version. 24 | 25 | *** Requires rendering resolution to be set to 1xPSP 26 | 27 | *** Surprisingly, looks reasonably good on low resolution (720p/768p) 28 | displays... 29 | */ 30 | 31 | //=== Config 32 | #define BRIGHTEN_SCANLINES 16.0 // "Brighten Scanlines" - default: 16.0, min: 1.0, max: 32.0, step: 0.5 33 | // (brightness of horizontal lines) 34 | #define BRIGHTEN_LCD 4.0 // "Brighten LCD" - default: 4.0, min: 1.0, max: 12.0, step: 0.1 35 | // (brightness of vertical lines) 36 | 37 | //================ 38 | #ifdef GL_ES 39 | precision mediump float; 40 | precision mediump int; 41 | // For android, use this instead... 42 | //precision highp float; 43 | //precision highp int; 44 | // 45 | #endif 46 | 47 | //================ 48 | #define PI 3.141592654 49 | 50 | #define target_gamma 2.21 51 | #define display_gamma 2.2 52 | #define r 0.98 53 | #define g 0.795 54 | #define b 0.98 55 | #define rg 0.04 56 | #define rb 0.01 57 | #define gr 0.20 58 | #define gb 0.01 59 | #define br -0.18 60 | #define bg 0.165 61 | 62 | //================ 63 | uniform sampler2D sampler0; 64 | uniform vec2 u_texelDelta; 65 | varying vec2 v_texcoord0; 66 | 67 | // Have to use standard names to ensure compatibility with 68 | // Vulkan backend... 69 | varying vec2 v_texcoord1; // TextureSize 70 | 71 | //================ 72 | const float INV_BRIGHTEN_SCANLINES_INC = 1.0 / (BRIGHTEN_SCANLINES + 1.0); 73 | const float INV_BRIGHTEN_LCD_INC = 1.0 / (BRIGHTEN_LCD + 1.0); 74 | 75 | //================ 76 | void main() 77 | { 78 | // Generate LCD grid effect 79 | // > Note the 0.25 pixel offset -> required to ensure that 80 | // scanlines occur *between* pixels 81 | vec2 angle = 2.0 * PI * ((v_texcoord0.xy * v_texcoord1.xy) - 0.25); // v_texcoord1 == TextureSize 82 | 83 | float yfactor = (BRIGHTEN_SCANLINES + sin(angle.y)) * INV_BRIGHTEN_SCANLINES_INC; 84 | float xfactor = (BRIGHTEN_LCD + sin(angle.x)) * INV_BRIGHTEN_LCD_INC; 85 | 86 | // Get colour sample and apply colour correction 87 | vec2 centerCoord = floor(v_texcoord0.xy * v_texcoord1.xy) + vec2(0.5, 0.5); // v_texcoord1 == TextureSize 88 | vec3 colour = pow(texture2D(sampler0, u_texelDelta.xy * centerCoord).rgb, vec3(target_gamma)); 89 | colour = clamp(colour, 0.0, 1.0); 90 | colour = pow( 91 | mat3(r, rg, rb, 92 | gr, g, gb, 93 | br, bg, b) * colour, 94 | vec3(1.0 / display_gamma) 95 | ); 96 | 97 | // Apply LCD grid effect 98 | colour.rgb = yfactor * xfactor * colour.rgb; 99 | 100 | gl_FragColor = vec4(colour.rgb, 1.0); 101 | } 102 | -------------------------------------------------------------------------------- /lcd1x_sharp+psp_color_mobile.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | lcd1x_sharp+psp_color shader 3 | 4 | This is an attempt to make a shader with a non-blurry LCD effect. 5 | It combines the existing shader code: 6 | 7 | - Nearest neighbour scaling, taken from zfast_lcd 8 | [Original code copyright (C) 2017 Greg Hogan (SoltanGris42)] 9 | 10 | - lcd3x 'grille effect', but without colour seperation 11 | [Original code by Gigaherz, released into the public domain] 12 | [Code here derived from PPSSPP version of lcd3x made by LunaMoo] 13 | 14 | - psp colour correction 15 | [Original code written by hunterk, modified by Pokefan531 and 16 | released into the public domain] 17 | 18 | Code mashed together by jdgleaver... 19 | 20 | This program is free software; you can redistribute it and/or modify it 21 | under the terms of the GNU General Public License as published by the Free 22 | Software Foundation; either version 2 of the License, or (at your option) 23 | any later version. 24 | 25 | *** Requires rendering resolution to be set to 1xPSP 26 | 27 | *** Surprisingly, looks reasonably good on low resolution (720p/768p) 28 | displays... 29 | */ 30 | 31 | //=== Config 32 | #define BRIGHTEN_SCANLINES 16.0 // "Brighten Scanlines" - default: 16.0, min: 1.0, max: 32.0, step: 0.5 33 | // (brightness of horizontal lines) 34 | #define BRIGHTEN_LCD 4.0 // "Brighten LCD" - default: 4.0, min: 1.0, max: 12.0, step: 0.1 35 | // (brightness of vertical lines) 36 | 37 | //================ 38 | #ifdef GL_ES 39 | //precision mediump float; 40 | //precision mediump int; 41 | // For android, use this instead... 42 | precision highp float; 43 | precision highp int; 44 | #endif 45 | 46 | //================ 47 | #define PI 3.141592654 48 | 49 | #define target_gamma 2.21 50 | #define display_gamma 2.2 51 | #define r 0.98 52 | #define g 0.795 53 | #define b 0.98 54 | #define rg 0.04 55 | #define rb 0.01 56 | #define gr 0.20 57 | #define gb 0.01 58 | #define br -0.18 59 | #define bg 0.165 60 | 61 | //================ 62 | uniform sampler2D sampler0; 63 | uniform vec2 u_texelDelta; 64 | varying vec2 v_texcoord0; 65 | 66 | // Have to use standard names to ensure compatibility with 67 | // Vulkan backend... 68 | varying vec2 v_texcoord1; // TextureSize 69 | 70 | //================ 71 | const float INV_BRIGHTEN_SCANLINES_INC = 1.0 / (BRIGHTEN_SCANLINES + 1.0); 72 | const float INV_BRIGHTEN_LCD_INC = 1.0 / (BRIGHTEN_LCD + 1.0); 73 | 74 | //================ 75 | void main() 76 | { 77 | // Generate LCD grid effect 78 | // > Note the 0.25 pixel offset -> required to ensure that 79 | // scanlines occur *between* pixels 80 | vec2 angle = 2.0 * PI * ((v_texcoord0.xy * v_texcoord1.xy) - 0.25); // v_texcoord1 == TextureSize 81 | 82 | float yfactor = (BRIGHTEN_SCANLINES + sin(angle.y)) * INV_BRIGHTEN_SCANLINES_INC; 83 | float xfactor = (BRIGHTEN_LCD + sin(angle.x)) * INV_BRIGHTEN_LCD_INC; 84 | 85 | // Get colour sample and apply colour correction 86 | vec2 centerCoord = floor(v_texcoord0.xy * v_texcoord1.xy) + vec2(0.5, 0.5); // v_texcoord1 == TextureSize 87 | vec3 colour = pow(texture2D(sampler0, u_texelDelta.xy * centerCoord).rgb, vec3(target_gamma)); 88 | colour = clamp(colour, 0.0, 1.0); 89 | colour = pow( 90 | mat3(r, rg, rb, 91 | gr, g, gb, 92 | br, bg, b) * colour, 93 | vec3(1.0 / display_gamma) 94 | ); 95 | 96 | // Apply LCD grid effect 97 | colour.rgb = yfactor * xfactor * colour.rgb; 98 | 99 | gl_FragColor = vec4(colour.rgb, 1.0); 100 | } 101 | -------------------------------------------------------------------------------- /lcd1x_sharp.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | lcd1x_sharp shader 3 | 4 | This is an attempt to make a shader with a non-blurry LCD effect. 5 | It combines the existing shader code: 6 | 7 | - Nearest neighbour scaling, taken from zfast_lcd 8 | [Original code copyright (C) 2017 Greg Hogan (SoltanGris42)] 9 | 10 | - lcd3x 'grille effect', but without colour seperation 11 | [Original code by Gigaherz, released into the public domain] 12 | [Code here derived from PPSSPP version of lcd3x made by LunaMoo] 13 | 14 | Code mashed together by jdgleaver... 15 | 16 | This program is free software; you can redistribute it and/or modify it 17 | under the terms of the GNU General Public License as published by the Free 18 | Software Foundation; either version 2 of the License, or (at your option) 19 | any later version. 20 | 21 | *** Requires rendering resolution to be set to 1xPSP 22 | 23 | *** Surprisingly, looks reasonably good on low resolution (720p/768p) 24 | displays... 25 | */ 26 | 27 | //=== Config 28 | #define BRIGHTEN_SCANLINES 16.0 // "Brighten Scanlines" - default: 16.0, min: 1.0, max: 32.0, step: 0.5 29 | // (brightness of horizontal lines) 30 | #define BRIGHTEN_LCD 4.0 // "Brighten LCD" - default: 4.0, min: 1.0, max: 12.0, step: 0.1 31 | // (brightness of vertical lines) 32 | 33 | //================ 34 | #ifdef GL_ES 35 | precision mediump float; 36 | precision mediump int; 37 | // For android, use this instead... 38 | //precision highp float; 39 | //precision highp int; 40 | // 41 | #endif 42 | 43 | //================ 44 | #define PI 3.141592654 45 | 46 | //================ 47 | uniform sampler2D sampler0; 48 | uniform vec2 u_texelDelta; 49 | varying vec2 v_texcoord0; 50 | 51 | // Have to use standard names to ensure compatibility with 52 | // Vulkan backend... 53 | varying vec2 v_texcoord1; // TextureSize 54 | 55 | //================ 56 | const float INV_BRIGHTEN_SCANLINES_INC = 1.0 / (BRIGHTEN_SCANLINES + 1.0); 57 | const float INV_BRIGHTEN_LCD_INC = 1.0 / (BRIGHTEN_LCD + 1.0); 58 | 59 | //================ 60 | void main() 61 | { 62 | // Generate LCD grid effect 63 | // > Note the 0.25 pixel offset -> required to ensure that 64 | // scanlines occur *between* pixels 65 | vec2 angle = 2.0 * PI * ((v_texcoord0.xy * v_texcoord1.xy) - 0.25); // v_texcoord1 == TextureSize 66 | 67 | float yfactor = (BRIGHTEN_SCANLINES + sin(angle.y)) * INV_BRIGHTEN_SCANLINES_INC; 68 | float xfactor = (BRIGHTEN_LCD + sin(angle.x)) * INV_BRIGHTEN_LCD_INC; 69 | 70 | // Get colour sample 71 | vec2 centerCoord = floor(v_texcoord0.xy * v_texcoord1.xy) + vec2(0.5, 0.5); // v_texcoord1 == TextureSize 72 | vec3 colour = texture2D(sampler0, u_texelDelta.xy * centerCoord).rgb; 73 | 74 | // Apply LCD grid effect 75 | colour.rgb = yfactor * xfactor * colour.rgb; 76 | 77 | gl_FragColor = vec4(colour.rgb, 1.0); 78 | } 79 | -------------------------------------------------------------------------------- /lcd1x_sharp.ini: -------------------------------------------------------------------------------- 1 | [LCD1x Sharp] 2 | Name=LCD1x Sharp 3 | Author=Gigaherz, LunaMoo, Greg Hogan (SoltanGris42), mashed up by jdgleaver 4 | Fragment=lcd1x_sharp.fsh 5 | Vertex=lcd1x_sharp.vsh 6 | OutputResolution=True 7 | [LCD1x Sharp (Mobile)] 8 | Name=LCD1x Sharp (Mobile) 9 | Author=Gigaherz, LunaMoo, Greg Hogan (SoltanGris42), mashed up by jdgleaver 10 | Fragment=lcd1x_sharp_mobile.fsh 11 | Vertex=lcd1x_sharp.vsh 12 | OutputResolution=True 13 | [LCD1x Sharp + PSP Color] 14 | Name=LCD1x Sharp + PSP Color 15 | Author=Gigaherz, LunaMoo, Greg Hogan (SoltanGris42), hunterk, Pokefan531, mashed up by jdgleaver 16 | Fragment=lcd1x_sharp+psp_color.fsh 17 | Vertex=lcd1x_sharp.vsh 18 | OutputResolution=True 19 | [LCD1x Sharp + PSP Color (Mobile)] 20 | Name=LCD1x Sharp + PSP Color (Mobile) 21 | Author=Gigaherz, LunaMoo, Greg Hogan (SoltanGris42), hunterk, Pokefan531, mashed up by jdgleaver 22 | Fragment=lcd1x_sharp+psp_color_mobile.fsh 23 | Vertex=lcd1x_sharp.vsh 24 | OutputResolution=True 25 | -------------------------------------------------------------------------------- /lcd1x_sharp.vsh: -------------------------------------------------------------------------------- 1 | /* 2 | lcd1x_sharp shader 3 | 4 | This is an attempt to make a shader with a non-blurry LCD effect. 5 | It combines the existing shader code: 6 | 7 | - Nearest neighbour scaling, taken from zfast_lcd 8 | [Original code copyright (C) 2017 Greg Hogan (SoltanGris42)] 9 | 10 | - lcd3x 'grille effect', but without colour seperation 11 | [Original code by Gigaherz, released into the public domain] 12 | [Code here derived from PPSSPP version of lcd3x made by LunaMoo] 13 | 14 | Code mashed together by jdgleaver... 15 | 16 | This program is free software; you can redistribute it and/or modify it 17 | under the terms of the GNU General Public License as published by the Free 18 | Software Foundation; either version 2 of the License, or (at your option) 19 | any later version. 20 | 21 | *** Requires rendering resolution to be set to 1xPSP 22 | 23 | *** Surprisingly, looks reasonably good on low resolution (720p/768p) 24 | displays... 25 | */ 26 | 27 | uniform vec2 u_texelDelta; 28 | attribute vec4 a_position; 29 | attribute vec2 a_texcoord0; 30 | varying vec2 v_texcoord0; 31 | 32 | // Have to use standard names to ensure compatibility with 33 | // Vulkan backend... 34 | varying vec2 v_texcoord1; // TextureSize 35 | 36 | void main() 37 | { 38 | v_texcoord0 = a_texcoord0; 39 | gl_Position = a_position; 40 | v_texcoord1 = 1.0 / u_texelDelta.xy; // TextureSize 41 | } 42 | -------------------------------------------------------------------------------- /lcd1x_sharp_mobile.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | lcd1x_sharp shader 3 | 4 | This is an attempt to make a shader with a non-blurry LCD effect. 5 | It combines the existing shader code: 6 | 7 | - Nearest neighbour scaling, taken from zfast_lcd 8 | [Original code copyright (C) 2017 Greg Hogan (SoltanGris42)] 9 | 10 | - lcd3x 'grille effect', but without colour seperation 11 | [Original code by Gigaherz, released into the public domain] 12 | [Code here derived from PPSSPP version of lcd3x made by LunaMoo] 13 | 14 | Code mashed together by jdgleaver... 15 | 16 | This program is free software; you can redistribute it and/or modify it 17 | under the terms of the GNU General Public License as published by the Free 18 | Software Foundation; either version 2 of the License, or (at your option) 19 | any later version. 20 | 21 | *** Requires rendering resolution to be set to 1xPSP 22 | 23 | *** Surprisingly, looks reasonably good on low resolution (720p/768p) 24 | displays... 25 | */ 26 | 27 | //=== Config 28 | #define BRIGHTEN_SCANLINES 16.0 // "Brighten Scanlines" - default: 16.0, min: 1.0, max: 32.0, step: 0.5 29 | // (brightness of horizontal lines) 30 | #define BRIGHTEN_LCD 4.0 // "Brighten LCD" - default: 4.0, min: 1.0, max: 12.0, step: 0.1 31 | // (brightness of vertical lines) 32 | 33 | //================ 34 | #ifdef GL_ES 35 | //precision mediump float; 36 | //precision mediump int; 37 | // For android, use this instead... 38 | precision highp float; 39 | precision highp int; 40 | #endif 41 | 42 | //================ 43 | #define PI 3.141592654 44 | 45 | //================ 46 | uniform sampler2D sampler0; 47 | uniform vec2 u_texelDelta; 48 | varying vec2 v_texcoord0; 49 | 50 | // Have to use standard names to ensure compatibility with 51 | // Vulkan backend... 52 | varying vec2 v_texcoord1; // TextureSize 53 | 54 | //================ 55 | const float INV_BRIGHTEN_SCANLINES_INC = 1.0 / (BRIGHTEN_SCANLINES + 1.0); 56 | const float INV_BRIGHTEN_LCD_INC = 1.0 / (BRIGHTEN_LCD + 1.0); 57 | 58 | //================ 59 | void main() 60 | { 61 | // Generate LCD grid effect 62 | // > Note the 0.25 pixel offset -> required to ensure that 63 | // scanlines occur *between* pixels 64 | vec2 angle = 2.0 * PI * ((v_texcoord0.xy * v_texcoord1.xy) - 0.25); // v_texcoord1 == TextureSize 65 | 66 | float yfactor = (BRIGHTEN_SCANLINES + sin(angle.y)) * INV_BRIGHTEN_SCANLINES_INC; 67 | float xfactor = (BRIGHTEN_LCD + sin(angle.x)) * INV_BRIGHTEN_LCD_INC; 68 | 69 | // Get colour sample 70 | vec2 centerCoord = floor(v_texcoord0.xy * v_texcoord1.xy) + vec2(0.5, 0.5); // v_texcoord1 == TextureSize 71 | vec3 colour = texture2D(sampler0, u_texelDelta.xy * centerCoord).rgb; 72 | 73 | // Apply LCD grid effect 74 | colour.rgb = yfactor * xfactor * colour.rgb; 75 | 76 | gl_FragColor = vec4(colour.rgb, 1.0); 77 | } 78 | -------------------------------------------------------------------------------- /lcd3x+psp_color.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | lcd3x+psp_color shader 3 | 4 | - Original 'lcd3x' code by Gigaherz, released into the public domain 5 | [Code here derived from PPSSPP version of lcd3x made by LunaMoo] 6 | 7 | - Original 'psp_color' code written by hunterk, modified by Pokefan531 and 8 | released into the public domain 9 | 10 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 11 | 12 | This program is free software; you can redistribute it and/or modify it 13 | under the terms of the GNU General Public License as published by the Free 14 | Software Foundation; either version 2 of the License, or (at your option) 15 | any later version. 16 | 17 | *** Requires rendering resolution to be set to 1xPSP 18 | */ 19 | 20 | //=== Config 21 | #define BRIGHTEN_SCANLINES 16.0 // "Brighten Scanlines" - default: 16.0, min: 1.0, max: 32.0, step: 0.5 22 | // (brightness of horizontal lines) 23 | #define BRIGHTEN_LCD 4.0 // "Brighten LCD" - default: 4.0, min: 1.0, max: 12.0, step: 0.1 24 | // (brightness of vertical lines) 25 | 26 | //================ 27 | #ifdef GL_ES 28 | precision mediump float; 29 | precision mediump int; 30 | // For android, use this instead... 31 | //precision highp float; 32 | //precision highp int; 33 | // 34 | #endif 35 | 36 | //================ 37 | #define PI 3.141592654 38 | 39 | #define target_gamma 2.21 40 | #define display_gamma 2.2 41 | #define r 0.98 42 | #define g 0.795 43 | #define b 0.98 44 | #define rg 0.04 45 | #define rb 0.01 46 | #define gr 0.20 47 | #define gb 0.01 48 | #define br -0.18 49 | #define bg 0.165 50 | 51 | //================ 52 | uniform sampler2D sampler0; 53 | varying vec2 v_texcoord0; 54 | 55 | // Have to use standard names to ensure compatibility with 56 | // Vulkan backend... 57 | varying vec2 v_texcoord1; // TextureSize 58 | 59 | //================ 60 | const float INV_BRIGHTEN_SCANLINES_INC = 1.0 / (BRIGHTEN_SCANLINES + 1.0); 61 | const float INV_BRIGHTEN_LCD_INC = 1.0 / (BRIGHTEN_LCD + 1.0); 62 | 63 | //================ 64 | void main() 65 | { 66 | // Generate LCD effect 67 | const vec3 offsets = PI * vec3(0.5, 0.5 - (2.0 / 3.0), 0.5 - (4.0 / 3.0)); 68 | 69 | // > Originally had a defined 'scanline size' here, but we can determine this 70 | // from the current texture size... 71 | vec2 angle = PI * v_texcoord0.xy * 2.0 * v_texcoord1.xy; 72 | 73 | float yfactor = (BRIGHTEN_SCANLINES + sin(angle.y)) * INV_BRIGHTEN_SCANLINES_INC; 74 | vec3 xfactors = (BRIGHTEN_LCD + sin(angle.x + offsets)) * INV_BRIGHTEN_LCD_INC; 75 | 76 | // Get colour sample and apply colour correction 77 | vec3 colour = pow(texture2D(sampler0, v_texcoord0.xy).rgb, vec3(target_gamma)); 78 | colour = clamp(colour, 0.0, 1.0); 79 | colour = pow( 80 | mat3(r, rg, rb, 81 | gr, g, gb, 82 | br, bg, b) * colour, 83 | vec3(1.0 / display_gamma) 84 | ); 85 | 86 | // Apply LCD effect 87 | colour.rgb = yfactor * xfactors * colour.rgb; 88 | 89 | gl_FragColor = vec4(colour.rgb, 1.0); 90 | } 91 | -------------------------------------------------------------------------------- /lcd3x+psp_color_mobile.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | lcd3x+psp_color shader 3 | 4 | - Original 'lcd3x' code by Gigaherz, released into the public domain 5 | [Code here derived from PPSSPP version of lcd3x made by LunaMoo] 6 | 7 | - Original 'psp_color' code written by hunterk, modified by Pokefan531 and 8 | released into the public domain 9 | 10 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 11 | 12 | This program is free software; you can redistribute it and/or modify it 13 | under the terms of the GNU General Public License as published by the Free 14 | Software Foundation; either version 2 of the License, or (at your option) 15 | any later version. 16 | 17 | *** Requires rendering resolution to be set to 1xPSP 18 | */ 19 | 20 | //=== Config 21 | #define BRIGHTEN_SCANLINES 16.0 // "Brighten Scanlines" - default: 16.0, min: 1.0, max: 32.0, step: 0.5 22 | // (brightness of horizontal lines) 23 | #define BRIGHTEN_LCD 4.0 // "Brighten LCD" - default: 4.0, min: 1.0, max: 12.0, step: 0.1 24 | // (brightness of vertical lines) 25 | 26 | //================ 27 | #ifdef GL_ES 28 | //precision mediump float; 29 | //precision mediump int; 30 | // For android, use this instead... 31 | precision highp float; 32 | precision highp int; 33 | #endif 34 | 35 | //================ 36 | #define PI 3.141592654 37 | 38 | #define target_gamma 2.21 39 | #define display_gamma 2.2 40 | #define r 0.98 41 | #define g 0.795 42 | #define b 0.98 43 | #define rg 0.04 44 | #define rb 0.01 45 | #define gr 0.20 46 | #define gb 0.01 47 | #define br -0.18 48 | #define bg 0.165 49 | 50 | //================ 51 | uniform sampler2D sampler0; 52 | varying vec2 v_texcoord0; 53 | 54 | // Have to use standard names to ensure compatibility with 55 | // Vulkan backend... 56 | varying vec2 v_texcoord1; // TextureSize 57 | 58 | //================ 59 | const float INV_BRIGHTEN_SCANLINES_INC = 1.0 / (BRIGHTEN_SCANLINES + 1.0); 60 | const float INV_BRIGHTEN_LCD_INC = 1.0 / (BRIGHTEN_LCD + 1.0); 61 | 62 | //================ 63 | void main() 64 | { 65 | // Generate LCD effect 66 | const vec3 offsets = PI * vec3(0.5, 0.5 - (2.0 / 3.0), 0.5 - (4.0 / 3.0)); 67 | 68 | // > Originally had a defined 'scanline size' here, but we can determine this 69 | // from the current texture size... 70 | vec2 angle = PI * v_texcoord0.xy * 2.0 * v_texcoord1.xy; 71 | 72 | float yfactor = (BRIGHTEN_SCANLINES + sin(angle.y)) * INV_BRIGHTEN_SCANLINES_INC; 73 | vec3 xfactors = (BRIGHTEN_LCD + sin(angle.x + offsets)) * INV_BRIGHTEN_LCD_INC; 74 | 75 | // Get colour sample and apply colour correction 76 | vec3 colour = pow(texture2D(sampler0, v_texcoord0.xy).rgb, vec3(target_gamma)); 77 | colour = clamp(colour, 0.0, 1.0); 78 | colour = pow( 79 | mat3(r, rg, rb, 80 | gr, g, gb, 81 | br, bg, b) * colour, 82 | vec3(1.0 / display_gamma) 83 | ); 84 | 85 | // Apply LCD effect 86 | colour.rgb = yfactor * xfactors * colour.rgb; 87 | 88 | gl_FragColor = vec4(colour.rgb, 1.0); 89 | } 90 | -------------------------------------------------------------------------------- /lcd3x.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | lcd3x shader 3 | 4 | - Original code by Gigaherz, released into the public domain 5 | [Code here derived from PPSSPP version of lcd3x made by LunaMoo] 6 | 7 | - This version 'tweaked' by jdgleaver... 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 2 of the License, or (at your option) 12 | any later version. 13 | 14 | *** Requires rendering resolution to be set to 1xPSP 15 | */ 16 | 17 | //=== Config 18 | #define BRIGHTEN_SCANLINES 16.0 // "Brighten Scanlines" - default: 16.0, min: 1.0, max: 32.0, step: 0.5 19 | // (brightness of horizontal lines) 20 | #define BRIGHTEN_LCD 4.0 // "Brighten LCD" - default: 4.0, min: 1.0, max: 12.0, step: 0.1 21 | // (brightness of vertical lines) 22 | 23 | //================ 24 | #ifdef GL_ES 25 | precision mediump float; 26 | precision mediump int; 27 | // For android, use this instead... 28 | //precision highp float; 29 | //precision highp int; 30 | // 31 | #endif 32 | 33 | //================ 34 | #define PI 3.141592654 35 | 36 | //================ 37 | uniform sampler2D sampler0; 38 | varying vec2 v_texcoord0; 39 | 40 | // Have to use standard names to ensure compatibility with 41 | // Vulkan backend... 42 | varying vec2 v_texcoord1; // TextureSize 43 | 44 | //================ 45 | const float INV_BRIGHTEN_SCANLINES_INC = 1.0 / (BRIGHTEN_SCANLINES + 1.0); 46 | const float INV_BRIGHTEN_LCD_INC = 1.0 / (BRIGHTEN_LCD + 1.0); 47 | 48 | //================ 49 | void main() 50 | { 51 | // Generate LCD effect 52 | const vec3 offsets = PI * vec3(0.5, 0.5 - (2.0 / 3.0), 0.5 - (4.0 / 3.0)); 53 | 54 | // > Originally had a defined 'scanline size' here, but we can determine this 55 | // from the current texture size... 56 | vec2 angle = PI * v_texcoord0.xy * 2.0 * v_texcoord1.xy; 57 | 58 | float yfactor = (BRIGHTEN_SCANLINES + sin(angle.y)) * INV_BRIGHTEN_SCANLINES_INC; 59 | vec3 xfactors = (BRIGHTEN_LCD + sin(angle.x + offsets)) * INV_BRIGHTEN_LCD_INC; 60 | 61 | // Get colour sample 62 | vec3 colour = texture2D(sampler0, v_texcoord0.xy).xyz; 63 | 64 | // Apply LCD effect 65 | colour.rgb = yfactor * xfactors * colour.rgb; 66 | 67 | gl_FragColor = vec4(colour.rgb, 1.0); 68 | } 69 | -------------------------------------------------------------------------------- /lcd3x.ini: -------------------------------------------------------------------------------- 1 | [LCD3x] 2 | Name=LCD3x 3 | Author=Gigaherz, LunaMoo, messed about with by jdgleaver 4 | Fragment=lcd3x.fsh 5 | Vertex=lcd3x.vsh 6 | OutputResolution=True 7 | [LCD3x (Mobile)] 8 | Name=LCD3x (Mobile) 9 | Author=Gigaherz, LunaMoo, messed about with by jdgleaver 10 | Fragment=lcd3x_mobile.fsh 11 | Vertex=lcd3x.vsh 12 | OutputResolution=True 13 | [LCD3x + PSP Color] 14 | Name=LCD3x + PSP Color 15 | Author=Gigaherz, LunaMoo, hunterk, Pokefan531, messed about with by jdgleaver 16 | Fragment=lcd3x+psp_color.fsh 17 | Vertex=lcd3x.vsh 18 | OutputResolution=True 19 | [LCD3x + PSP Color (Mobile)] 20 | Name=LCD3x + PSP Color (Mobile) 21 | Author=Gigaherz, LunaMoo, hunterk, Pokefan531, messed about with by jdgleaver 22 | Fragment=lcd3x+psp_color_mobile.fsh 23 | Vertex=lcd3x.vsh 24 | OutputResolution=True 25 | -------------------------------------------------------------------------------- /lcd3x.vsh: -------------------------------------------------------------------------------- 1 | /* 2 | lcd3x shader 3 | 4 | - Original code by Gigaherz, released into the public domain 5 | [Code here derived from PPSSPP version of lcd3x made by LunaMoo] 6 | 7 | - This version 'tweaked' by jdgleaver... 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 2 of the License, or (at your option) 12 | any later version. 13 | 14 | *** Requires rendering resolution to be set to 1xPSP 15 | */ 16 | 17 | uniform vec2 u_texelDelta; 18 | attribute vec4 a_position; 19 | attribute vec2 a_texcoord0; 20 | varying vec2 v_texcoord0; 21 | 22 | // Have to use standard names to ensure compatibility with 23 | // Vulkan backend... 24 | varying vec2 v_texcoord1; // TextureSize 25 | 26 | void main() 27 | { 28 | v_texcoord0 = a_texcoord0; 29 | gl_Position = a_position; 30 | 31 | v_texcoord1 = 1.0 / u_texelDelta; 32 | } 33 | -------------------------------------------------------------------------------- /lcd3x_mobile.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | lcd3x shader 3 | 4 | - Original code by Gigaherz, released into the public domain 5 | [Code here derived from PPSSPP version of lcd3x made by LunaMoo] 6 | 7 | - This version 'tweaked' by jdgleaver... 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 2 of the License, or (at your option) 12 | any later version. 13 | 14 | *** Requires rendering resolution to be set to 1xPSP 15 | */ 16 | 17 | //=== Config 18 | #define BRIGHTEN_SCANLINES 16.0 // "Brighten Scanlines" - default: 16.0, min: 1.0, max: 32.0, step: 0.5 19 | // (brightness of horizontal lines) 20 | #define BRIGHTEN_LCD 4.0 // "Brighten LCD" - default: 4.0, min: 1.0, max: 12.0, step: 0.1 21 | // (brightness of vertical lines) 22 | 23 | //================ 24 | #ifdef GL_ES 25 | //precision mediump float; 26 | //precision mediump int; 27 | // For android, use this instead... 28 | precision highp float; 29 | precision highp int; 30 | #endif 31 | 32 | //================ 33 | #define PI 3.141592654 34 | 35 | //================ 36 | uniform sampler2D sampler0; 37 | varying vec2 v_texcoord0; 38 | 39 | // Have to use standard names to ensure compatibility with 40 | // Vulkan backend... 41 | varying vec2 v_texcoord1; // TextureSize 42 | 43 | //================ 44 | const float INV_BRIGHTEN_SCANLINES_INC = 1.0 / (BRIGHTEN_SCANLINES + 1.0); 45 | const float INV_BRIGHTEN_LCD_INC = 1.0 / (BRIGHTEN_LCD + 1.0); 46 | 47 | //================ 48 | void main() 49 | { 50 | // Generate LCD effect 51 | const vec3 offsets = PI * vec3(0.5, 0.5 - (2.0 / 3.0), 0.5 - (4.0 / 3.0)); 52 | 53 | // > Originally had a defined 'scanline size' here, but we can determine this 54 | // from the current texture size... 55 | vec2 angle = PI * v_texcoord0.xy * 2.0 * v_texcoord1.xy; 56 | 57 | float yfactor = (BRIGHTEN_SCANLINES + sin(angle.y)) * INV_BRIGHTEN_SCANLINES_INC; 58 | vec3 xfactors = (BRIGHTEN_LCD + sin(angle.x + offsets)) * INV_BRIGHTEN_LCD_INC; 59 | 60 | // Get colour sample 61 | vec3 colour = texture2D(sampler0, v_texcoord0.xy).xyz; 62 | 63 | // Apply LCD effect 64 | colour.rgb = yfactor * xfactors * colour.rgb; 65 | 66 | gl_FragColor = vec4(colour.rgb, 1.0); 67 | } 68 | -------------------------------------------------------------------------------- /psp_color.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | psp_color vertex shader 3 | 4 | Original code written by hunterk, modified by Pokefan531 and 5 | released into the public domain 6 | 7 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 2 of the License, or (at your option) 12 | any later version. 13 | 14 | Notes: This shader replicates the LCD dynamics of the PSP 1000 and PSP 2000 15 | */ 16 | 17 | //================ 18 | #ifdef GL_ES 19 | precision mediump float; 20 | precision mediump int; 21 | // For android, use this instead... 22 | //precision highp float; 23 | //precision highp int; 24 | // 25 | #endif 26 | 27 | //================ 28 | #define target_gamma 2.21 29 | #define display_gamma 2.2 30 | #define r 0.98 31 | #define g 0.795 32 | #define b 0.98 33 | #define rg 0.04 34 | #define rb 0.01 35 | #define gr 0.20 36 | #define gb 0.01 37 | #define br -0.18 38 | #define bg 0.165 39 | 40 | //================ 41 | uniform sampler2D sampler0; 42 | varying vec2 v_texcoord0; 43 | 44 | //================ 45 | void main() 46 | { 47 | // Apply colour correction 48 | vec3 screen = pow(texture2D(sampler0, v_texcoord0.xy).rgb, vec3(target_gamma)); 49 | screen = clamp(screen, 0.0, 1.0); 50 | screen = pow( 51 | mat3(r, rg, rb, 52 | gr, g, gb, 53 | br, bg, b) * screen, 54 | vec3(1.0 / display_gamma) 55 | ); 56 | 57 | gl_FragColor = vec4(screen, 1.0); 58 | } 59 | -------------------------------------------------------------------------------- /psp_color.ini: -------------------------------------------------------------------------------- 1 | [PSP Color] 2 | Name=PSP Color 3 | Author=hunterk, Pokefan531 (ported by jdgleaver) 4 | Fragment=psp_color.fsh 5 | Vertex=psp_color.vsh 6 | OutputResolution=True 7 | [PSP Color (Mobile)] 8 | Name=PSP Color (Mobile) 9 | Author=hunterk, Pokefan531 (ported by jdgleaver) 10 | Fragment=psp_color_mobile.fsh 11 | Vertex=psp_color.vsh 12 | OutputResolution=True 13 | -------------------------------------------------------------------------------- /psp_color.vsh: -------------------------------------------------------------------------------- 1 | /* 2 | psp_color vertex shader 3 | 4 | Original code written by hunterk, modified by Pokefan531 and 5 | released into the public domain 6 | 7 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 2 of the License, or (at your option) 12 | any later version. 13 | */ 14 | 15 | attribute vec4 a_position; 16 | attribute vec2 a_texcoord0; 17 | varying vec2 v_texcoord0; 18 | 19 | void main() 20 | { 21 | v_texcoord0 = a_texcoord0; // + 0.000001; // HLSL precision workaround (is this needed???) 22 | gl_Position = a_position; 23 | } 24 | -------------------------------------------------------------------------------- /psp_color_mobile.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | psp_color vertex shader 3 | 4 | Original code written by hunterk, modified by Pokefan531 and 5 | released into the public domain 6 | 7 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 2 of the License, or (at your option) 12 | any later version. 13 | 14 | Notes: This shader replicates the LCD dynamics of the PSP 1000 and PSP 2000 15 | */ 16 | 17 | //================ 18 | #ifdef GL_ES 19 | //precision mediump float; 20 | //precision mediump int; 21 | // For android, use this instead... 22 | precision highp float; 23 | precision highp int; 24 | #endif 25 | 26 | //================ 27 | #define target_gamma 2.21 28 | #define display_gamma 2.2 29 | #define r 0.98 30 | #define g 0.795 31 | #define b 0.98 32 | #define rg 0.04 33 | #define rb 0.01 34 | #define gr 0.20 35 | #define gb 0.01 36 | #define br -0.18 37 | #define bg 0.165 38 | 39 | //================ 40 | uniform sampler2D sampler0; 41 | varying vec2 v_texcoord0; 42 | 43 | //================ 44 | void main() 45 | { 46 | // Apply colour correction 47 | vec3 screen = pow(texture2D(sampler0, v_texcoord0.xy).rgb, vec3(target_gamma)); 48 | screen = clamp(screen, 0.0, 1.0); 49 | screen = pow( 50 | mat3(r, rg, rb, 51 | gr, g, gb, 52 | br, bg, b) * screen, 53 | vec3(1.0 / display_gamma) 54 | ); 55 | 56 | gl_FragColor = vec4(screen, 1.0); 57 | } 58 | -------------------------------------------------------------------------------- /zfast_lcd+psp_color.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | zfast_lcd+psp_color - A very simple LCD shader meant to be used at 1080p 3 | 4 | - Original 'zfast_lcd' code copyright (C) 2017 Greg Hogan (SoltanGris42) 5 | 6 | - Original 'psp_color' code written by hunterk, modified by Pokefan531 and 7 | released into the public domain 8 | 9 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 10 | 11 | This program is free software; you can redistribute it and/or modify it 12 | under the terms of the GNU General Public License as published by the Free 13 | Software Foundation; either version 2 of the License, or (at your option) 14 | any later version. 15 | 16 | Notes: This shader does nearest neighbor scaling of the game and then 17 | darkens the border pixels to imitate an LCD screen. You can change 18 | the darkness/thickness of the borders. It also applies colour 19 | correction to replicate the LCD dynamics of the PSP 1000 and PSP 2000. 20 | 21 | *** REQUIRES PPSSPP rendering resolution to be set to 1 x PSP 22 | 23 | *** REQUIRES a display resolution of at least 1080p (otherwise grid 24 | effect will vanish...) 25 | */ 26 | 27 | 28 | //=== Config 29 | #define BORDERMULT 14.0 // "Border Multiplier" default: 14.0, min: -40.0, max: 40.0, step: 1.0 30 | 31 | //================ 32 | #ifdef GL_ES 33 | precision mediump float; 34 | precision mediump int; 35 | // For android, use this instead... 36 | //precision highp float; 37 | //precision highp int; 38 | // 39 | #endif 40 | 41 | //================ 42 | #define target_gamma 2.21 43 | #define display_gamma 2.2 44 | #define r 0.98 45 | #define g 0.795 46 | #define b 0.98 47 | #define rg 0.04 48 | #define rb 0.01 49 | #define gr 0.20 50 | #define gb 0.01 51 | #define br -0.18 52 | #define bg 0.165 53 | 54 | //================ 55 | uniform sampler2D sampler0; 56 | uniform vec2 u_texelDelta; 57 | varying vec2 v_texcoord0; 58 | 59 | // Dirty hack: this should be called 'TextureSize', but when PPSSPP 60 | // performs shader translation it only coverts variables with a fixed 61 | // set of names - so in order for this shader to work with the Vulkan 62 | // backend, we have to 'borrow' one of the v_texcoord variables... 63 | // (note that we could work around this cleanly by calculating texture 64 | // size inside the fragment shader, but this would have a performance 65 | // impact and would therefore be lame...) 66 | varying vec2 v_texcoord1; // TextureSize 67 | 68 | //================ 69 | void main() 70 | { 71 | // 72 | // Note to self: u_texelDelta.xy == 1 / TextureSize.xy 73 | // 74 | 75 | // Generate grid pattern 76 | vec2 texcoordInPixels = v_texcoord0.xy * v_texcoord1.xy; // v_texcoord1 == TextureSize 77 | vec2 centerCoord = floor(texcoordInPixels.xy) + vec2(0.5, 0.5); 78 | vec2 distFromCenter = abs(centerCoord - texcoordInPixels); 79 | 80 | float Y = max(distFromCenter.x, distFromCenter.y); 81 | 82 | Y = Y * Y; 83 | float YY = Y * Y; 84 | float YYY = YY * Y; 85 | 86 | float LineWeight = YY - 2.7 * YYY; 87 | LineWeight = 1.0 - BORDERMULT * LineWeight; 88 | 89 | // Apply colour correction 90 | vec3 screen = pow(texture2D(sampler0, u_texelDelta.xy * centerCoord).rgb, vec3(target_gamma)); 91 | screen = clamp(screen, 0.0, 1.0); 92 | screen = pow( 93 | mat3(r, rg, rb, 94 | gr, g, gb, 95 | br, bg, b) * screen, 96 | vec3(1.0 / display_gamma) 97 | ); 98 | 99 | // Add grid lines 100 | gl_FragColor = vec4(screen * LineWeight, 1.0); 101 | } 102 | -------------------------------------------------------------------------------- /zfast_lcd+psp_color.ini: -------------------------------------------------------------------------------- 1 | [zfast LCD + PSP Color] 2 | Name=zfast LCD + PSP Color 3 | Author=Greg Hogan (SoltanGris42), hunterk, Pokefan531 (ported by jdgleaver) 4 | Fragment=zfast_lcd+psp_color.fsh 5 | Vertex=zfast_lcd.vsh 6 | OutputResolution=True 7 | [zfast LCD + PSP Color (Mobile)] 8 | Name=zfast LCD + PSP Color (Mobile) 9 | Author=Greg Hogan (SoltanGris42), hunterk, Pokefan531 (ported by jdgleaver) 10 | Fragment=zfast_lcd+psp_color_mobile.fsh 11 | Vertex=zfast_lcd.vsh 12 | OutputResolution=True 13 | [zfast LCD HD + PSP Color] 14 | Name=zfast LCD HD + PSP Color 15 | Author=Greg Hogan (SoltanGris42), hunterk, Pokefan531 (ported by jdgleaver) 16 | Fragment=zfast_lcd_hd+psp_color.fsh 17 | Vertex=zfast_lcd.vsh 18 | OutputResolution=True 19 | [zfast LCD HD + PSP Color (Mobile)] 20 | Name=zfast LCD HD + PSP Color (Mobile) 21 | Author=Greg Hogan (SoltanGris42), hunterk, Pokefan531 (ported by jdgleaver) 22 | Fragment=zfast_lcd_hd+psp_color_mobile.fsh 23 | Vertex=zfast_lcd.vsh 24 | OutputResolution=True 25 | -------------------------------------------------------------------------------- /zfast_lcd+psp_color_mobile.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | zfast_lcd+psp_color - A very simple LCD shader meant to be used at 1080p 3 | 4 | - Original 'zfast_lcd' code copyright (C) 2017 Greg Hogan (SoltanGris42) 5 | 6 | - Original 'psp_color' code written by hunterk, modified by Pokefan531 and 7 | released into the public domain 8 | 9 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 10 | 11 | This program is free software; you can redistribute it and/or modify it 12 | under the terms of the GNU General Public License as published by the Free 13 | Software Foundation; either version 2 of the License, or (at your option) 14 | any later version. 15 | 16 | Notes: This shader does nearest neighbor scaling of the game and then 17 | darkens the border pixels to imitate an LCD screen. You can change 18 | the darkness/thickness of the borders. It also applies colour 19 | correction to replicate the LCD dynamics of the PSP 1000 and PSP 2000. 20 | 21 | *** REQUIRES PPSSPP rendering resolution to be set to 1 x PSP 22 | 23 | *** REQUIRES a display resolution of at least 1080p (otherwise grid 24 | effect will vanish...) 25 | */ 26 | 27 | 28 | //=== Config 29 | #define BORDERMULT 14.0 // "Border Multiplier" default: 14.0, min: -40.0, max: 40.0, step: 1.0 30 | 31 | //================ 32 | #ifdef GL_ES 33 | //precision mediump float; 34 | //precision mediump int; 35 | // For android, use this instead... 36 | precision highp float; 37 | precision highp int; 38 | #endif 39 | 40 | //================ 41 | #define target_gamma 2.21 42 | #define display_gamma 2.2 43 | #define r 0.98 44 | #define g 0.795 45 | #define b 0.98 46 | #define rg 0.04 47 | #define rb 0.01 48 | #define gr 0.20 49 | #define gb 0.01 50 | #define br -0.18 51 | #define bg 0.165 52 | 53 | //================ 54 | uniform sampler2D sampler0; 55 | uniform vec2 u_texelDelta; 56 | varying vec2 v_texcoord0; 57 | 58 | // Dirty hack: this should be called 'TextureSize', but when PPSSPP 59 | // performs shader translation it only coverts variables with a fixed 60 | // set of names - so in order for this shader to work with the Vulkan 61 | // backend, we have to 'borrow' one of the v_texcoord variables... 62 | // (note that we could work around this cleanly by calculating texture 63 | // size inside the fragment shader, but this would have a performance 64 | // impact and would therefore be lame...) 65 | varying vec2 v_texcoord1; // TextureSize 66 | 67 | //================ 68 | void main() 69 | { 70 | // 71 | // Note to self: u_texelDelta.xy == 1 / TextureSize.xy 72 | // 73 | 74 | // Generate grid pattern 75 | vec2 texcoordInPixels = v_texcoord0.xy * v_texcoord1.xy; // v_texcoord1 == TextureSize 76 | vec2 centerCoord = floor(texcoordInPixels.xy) + vec2(0.5, 0.5); 77 | vec2 distFromCenter = abs(centerCoord - texcoordInPixels); 78 | 79 | float Y = max(distFromCenter.x, distFromCenter.y); 80 | 81 | Y = Y * Y; 82 | float YY = Y * Y; 83 | float YYY = YY * Y; 84 | 85 | float LineWeight = YY - 2.7 * YYY; 86 | LineWeight = 1.0 - BORDERMULT * LineWeight; 87 | 88 | // Apply colour correction 89 | vec3 screen = pow(texture2D(sampler0, u_texelDelta.xy * centerCoord).rgb, vec3(target_gamma)); 90 | screen = clamp(screen, 0.0, 1.0); 91 | screen = pow( 92 | mat3(r, rg, rb, 93 | gr, g, gb, 94 | br, bg, b) * screen, 95 | vec3(1.0 / display_gamma) 96 | ); 97 | 98 | // Add grid lines 99 | gl_FragColor = vec4(screen * LineWeight, 1.0); 100 | } 101 | -------------------------------------------------------------------------------- /zfast_lcd.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | zfast_lcd - A very simple LCD shader meant to be used at 1080p 3 | 4 | Original code copyright (C) 2017 Greg Hogan (SoltanGris42) 5 | 6 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 7 | 8 | This program is free software; you can redistribute it and/or modify it 9 | under the terms of the GNU General Public License as published by the Free 10 | Software Foundation; either version 2 of the License, or (at your option) 11 | any later version. 12 | 13 | Notes: This shader just does nearest neighbor scaling of the game and then 14 | darkens the border pixels to imitate an LCD screen. You can change 15 | the darkness/thickness of the borders. 16 | 17 | *** REQUIRES PPSSPP rendering resolution to be set to 1 x PSP 18 | 19 | *** REQUIRES a display resolution of at least 1080p (otherwise grid 20 | effect will vanish...) 21 | */ 22 | 23 | 24 | //=== Config 25 | #define BORDERMULT 14.0 // "Border Multiplier" default: 14.0, min: -40.0, max: 40.0, step: 1.0 26 | 27 | //================ 28 | #ifdef GL_ES 29 | precision mediump float; 30 | precision mediump int; 31 | // For android, use this instead... 32 | //precision highp float; 33 | //precision highp int; 34 | // 35 | #endif 36 | 37 | //================ 38 | uniform sampler2D sampler0; 39 | uniform vec2 u_texelDelta; 40 | varying vec2 v_texcoord0; 41 | 42 | // Dirty hack: this should be called 'TextureSize', but when PPSSPP 43 | // performs shader translation it only coverts variables with a fixed 44 | // set of names - so in order for this shader to work with the Vulkan 45 | // backend, we have to 'borrow' one of the v_texcoord variables... 46 | // (note that we could work around this cleanly by calculating texture 47 | // size inside the fragment shader, but this would have a performance 48 | // impact and would therefore be lame...) 49 | varying vec2 v_texcoord1; // TextureSize 50 | 51 | //================ 52 | void main() 53 | { 54 | // 55 | // Note to self: u_texelDelta.xy == 1 / TextureSize.xy 56 | // 57 | 58 | // Generate grid pattern 59 | vec2 texcoordInPixels = v_texcoord0.xy * v_texcoord1.xy; // v_texcoord1 == TextureSize 60 | vec2 centerCoord = floor(texcoordInPixels.xy) + vec2(0.5, 0.5); 61 | vec2 distFromCenter = abs(centerCoord - texcoordInPixels); 62 | 63 | float Y = max(distFromCenter.x, distFromCenter.y); 64 | 65 | Y = Y * Y; 66 | float YY = Y * Y; 67 | float YYY = YY * Y; 68 | 69 | float LineWeight = YY - 2.7 * YYY; 70 | LineWeight = 1.0 - BORDERMULT * LineWeight; 71 | 72 | // Get colour sample and apply grid effect 73 | vec3 colour = texture2D(sampler0, u_texelDelta.xy * centerCoord).rgb * LineWeight; 74 | 75 | gl_FragColor = vec4(colour.rgb, 1.0); 76 | } 77 | -------------------------------------------------------------------------------- /zfast_lcd.ini: -------------------------------------------------------------------------------- 1 | [zfast LCD] 2 | Name=zfast LCD 3 | Author=Greg Hogan (SoltanGris42), ported by jdgleaver 4 | Fragment=zfast_lcd.fsh 5 | Vertex=zfast_lcd.vsh 6 | OutputResolution=True 7 | [zfast LCD (Mobile)] 8 | Name=zfast LCD (Mobile) 9 | Author=Greg Hogan (SoltanGris42), ported by jdgleaver 10 | Fragment=zfast_lcd_mobile.fsh 11 | Vertex=zfast_lcd.vsh 12 | OutputResolution=True 13 | [zfast LCD HD] 14 | Name=zfast LCD HD 15 | Author=Greg Hogan (SoltanGris42), ported by jdgleaver 16 | Fragment=zfast_lcd_hd.fsh 17 | Vertex=zfast_lcd.vsh 18 | OutputResolution=True 19 | [zfast LCD HD (Mobile)] 20 | Name=zfast LCD HD (Mobile) 21 | Author=Greg Hogan (SoltanGris42), ported by jdgleaver 22 | Fragment=zfast_lcd_hd_mobile.fsh 23 | Vertex=zfast_lcd.vsh 24 | OutputResolution=True 25 | -------------------------------------------------------------------------------- /zfast_lcd.vsh: -------------------------------------------------------------------------------- 1 | /* 2 | zfast_lcd vertex shader 3 | 4 | Original code copyright (C) 2017 Greg Hogan (SoltanGris42) 5 | 6 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 7 | 8 | This program is free software; you can redistribute it and/or modify it 9 | under the terms of the GNU General Public License as published by the Free 10 | Software Foundation; either version 2 of the License, or (at your option) 11 | any later version. 12 | */ 13 | 14 | uniform vec2 u_texelDelta; 15 | attribute vec4 a_position; 16 | attribute vec2 a_texcoord0; 17 | varying vec2 v_texcoord0; 18 | 19 | // Dirty hack: this should be called 'TextureSize', but when PPSSPP 20 | // performs shader translation it only coverts variables with a fixed 21 | // set of names - so in order for this shader to work with the Vulkan 22 | // backend, we have to 'borrow' one of the v_texcoord variables... 23 | // (note that we could work around this cleanly by calculating texture 24 | // size inside the fragment shader, but this would have a performance 25 | // impact and would therefore be lame...) 26 | varying vec2 v_texcoord1; // TextureSize 27 | 28 | void main() 29 | { 30 | v_texcoord0 = a_texcoord0; // + 0.000001; // HLSL precision workaround (is this needed???) 31 | gl_Position = a_position; 32 | v_texcoord1 = 1.0 / u_texelDelta.xy; // TextureSize 33 | } 34 | -------------------------------------------------------------------------------- /zfast_lcd_hd+psp_color.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | zfast_lcd_hd+psp_color - A very simple LCD shader meant to be used at 1080p 3 | at arbitrary PPSSPP rendering resolutions 4 | 5 | - Original 'zfast_lcd' code copyright (C) 2017 Greg Hogan (SoltanGris42) 6 | 7 | - Original 'psp_color' code written by hunterk, modified by Pokefan531 and 8 | released into the public domain 9 | 10 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 11 | 12 | This program is free software; you can redistribute it and/or modify it 13 | under the terms of the GNU General Public License as published by the Free 14 | Software Foundation; either version 2 of the License, or (at your option) 15 | any later version. 16 | 17 | Notes: This shader applies a grid effect, darkening the borders of 18 | 'virtual' pixels at the native PSP resolution to imitate an LCD 19 | screen. You can change the darkness/thickness of the borders. 20 | It also applies colour correction to replicate the LCD dynamics 21 | of the PSP 1000 and PSP 2000. 22 | 23 | While this shader works at arbritrary resolutions, the effect 24 | is not as pleasing as with the normal 'zfast_lcd+psp_color' shader 25 | at native PSP resolution. This is due to the fact that we can't 26 | do nearest neighbour screen scaling in any meaningful fashion 27 | here, so the results are somewhat 'smudgy'... 28 | 29 | *** REQUIRES a display resolution of at least 1080p (otherwise grid 30 | effect will vanish...) 31 | */ 32 | 33 | 34 | //=== Config 35 | #define BORDERMULT 14.0 // "Border Multiplier" default: 14.0, min: -40.0, max: 40.0, step: 1.0 36 | 37 | //================ 38 | #ifdef GL_ES 39 | precision mediump float; 40 | precision mediump int; 41 | // For android, use this instead... 42 | //precision highp float; 43 | //precision highp int; 44 | // 45 | #endif 46 | 47 | //================ 48 | #define target_gamma 2.21 49 | #define display_gamma 2.2 50 | #define r 0.98 51 | #define g 0.795 52 | #define b 0.98 53 | #define rg 0.04 54 | #define rb 0.01 55 | #define gr 0.20 56 | #define gb 0.01 57 | #define br -0.18 58 | #define bg 0.165 59 | 60 | //================ 61 | uniform sampler2D sampler0; 62 | uniform vec2 u_texelDelta; 63 | varying vec2 v_texcoord0; 64 | 65 | // Dirty hack: this should be called 'TextureSize', but when PPSSPP 66 | // performs shader translation it only coverts variables with a fixed 67 | // set of names - so in order for this shader to work with the Vulkan 68 | // backend, we have to 'borrow' one of the v_texcoord variables... 69 | // (note that we could work around this cleanly by calculating texture 70 | // size inside the fragment shader, but this would have a performance 71 | // impact and would therefore be lame...) 72 | varying vec2 v_texcoord1; // TextureSize 73 | 74 | //================ 75 | const float NATIVE_SCREEN_HEIGHT = 272.0; 76 | 77 | //================ 78 | void main() 79 | { 80 | // 81 | // Note to self: u_texelDelta.xy == 1 / TextureSize.xy 82 | // 83 | 84 | // Generate grid pattern (in native PSP coordinate space) 85 | vec2 texcoordInPixels = v_texcoord0.xy * v_texcoord1.xy * NATIVE_SCREEN_HEIGHT * u_texelDelta.y; // v_texcoord1 == TextureSize 86 | vec2 centerCoord = floor(texcoordInPixels.xy) + vec2(0.5, 0.5); 87 | vec2 distFromCenter = abs(centerCoord - texcoordInPixels); 88 | 89 | float Y = max(distFromCenter.x, distFromCenter.y); 90 | 91 | Y = Y * Y; 92 | float YY = Y * Y; 93 | float YYY = YY * Y; 94 | 95 | float LineWeight = YY - 2.7 * YYY; 96 | LineWeight = 1.0 - BORDERMULT * LineWeight; 97 | 98 | // Apply colour correction 99 | vec3 screen = pow(texture2D(sampler0, v_texcoord0.xy).rgb, vec3(target_gamma)); 100 | screen = clamp(screen, 0.0, 1.0); 101 | screen = pow( 102 | mat3(r, rg, rb, 103 | gr, g, gb, 104 | br, bg, b) * screen, 105 | vec3(1.0 / display_gamma) 106 | ); 107 | 108 | // Add grid lines 109 | gl_FragColor = vec4(screen * LineWeight, 1.0); 110 | } 111 | -------------------------------------------------------------------------------- /zfast_lcd_hd+psp_color_mobile.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | zfast_lcd_hd+psp_color - A very simple LCD shader meant to be used at 1080p 3 | at arbitrary PPSSPP rendering resolutions 4 | 5 | - Original 'zfast_lcd' code copyright (C) 2017 Greg Hogan (SoltanGris42) 6 | 7 | - Original 'psp_color' code written by hunterk, modified by Pokefan531 and 8 | released into the public domain 9 | 10 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 11 | 12 | This program is free software; you can redistribute it and/or modify it 13 | under the terms of the GNU General Public License as published by the Free 14 | Software Foundation; either version 2 of the License, or (at your option) 15 | any later version. 16 | 17 | Notes: This shader applies a grid effect, darkening the borders of 18 | 'virtual' pixels at the native PSP resolution to imitate an LCD 19 | screen. You can change the darkness/thickness of the borders. 20 | It also applies colour correction to replicate the LCD dynamics 21 | of the PSP 1000 and PSP 2000. 22 | 23 | While this shader works at arbritrary resolutions, the effect 24 | is not as pleasing as with the normal 'zfast_lcd+psp_color' shader 25 | at native PSP resolution. This is due to the fact that we can't 26 | do nearest neighbour screen scaling in any meaningful fashion 27 | here, so the results are somewhat 'smudgy'... 28 | 29 | *** REQUIRES a display resolution of at least 1080p (otherwise grid 30 | effect will vanish...) 31 | */ 32 | 33 | 34 | //=== Config 35 | #define BORDERMULT 14.0 // "Border Multiplier" default: 14.0, min: -40.0, max: 40.0, step: 1.0 36 | 37 | //================ 38 | #ifdef GL_ES 39 | //precision mediump float; 40 | //precision mediump int; 41 | // For android, use this instead... 42 | precision highp float; 43 | precision highp int; 44 | #endif 45 | 46 | //================ 47 | #define target_gamma 2.21 48 | #define display_gamma 2.2 49 | #define r 0.98 50 | #define g 0.795 51 | #define b 0.98 52 | #define rg 0.04 53 | #define rb 0.01 54 | #define gr 0.20 55 | #define gb 0.01 56 | #define br -0.18 57 | #define bg 0.165 58 | 59 | //================ 60 | uniform sampler2D sampler0; 61 | uniform vec2 u_texelDelta; 62 | varying vec2 v_texcoord0; 63 | 64 | // Dirty hack: this should be called 'TextureSize', but when PPSSPP 65 | // performs shader translation it only coverts variables with a fixed 66 | // set of names - so in order for this shader to work with the Vulkan 67 | // backend, we have to 'borrow' one of the v_texcoord variables... 68 | // (note that we could work around this cleanly by calculating texture 69 | // size inside the fragment shader, but this would have a performance 70 | // impact and would therefore be lame...) 71 | varying vec2 v_texcoord1; // TextureSize 72 | 73 | //================ 74 | const float NATIVE_SCREEN_HEIGHT = 272.0; 75 | 76 | //================ 77 | void main() 78 | { 79 | // 80 | // Note to self: u_texelDelta.xy == 1 / TextureSize.xy 81 | // 82 | 83 | // Generate grid pattern (in native PSP coordinate space) 84 | vec2 texcoordInPixels = v_texcoord0.xy * v_texcoord1.xy * NATIVE_SCREEN_HEIGHT * u_texelDelta.y; // v_texcoord1 == TextureSize 85 | vec2 centerCoord = floor(texcoordInPixels.xy) + vec2(0.5, 0.5); 86 | vec2 distFromCenter = abs(centerCoord - texcoordInPixels); 87 | 88 | float Y = max(distFromCenter.x, distFromCenter.y); 89 | 90 | Y = Y * Y; 91 | float YY = Y * Y; 92 | float YYY = YY * Y; 93 | 94 | float LineWeight = YY - 2.7 * YYY; 95 | LineWeight = 1.0 - BORDERMULT * LineWeight; 96 | 97 | // Apply colour correction 98 | vec3 screen = pow(texture2D(sampler0, v_texcoord0.xy).rgb, vec3(target_gamma)); 99 | screen = clamp(screen, 0.0, 1.0); 100 | screen = pow( 101 | mat3(r, rg, rb, 102 | gr, g, gb, 103 | br, bg, b) * screen, 104 | vec3(1.0 / display_gamma) 105 | ); 106 | 107 | // Add grid lines 108 | gl_FragColor = vec4(screen * LineWeight, 1.0); 109 | } 110 | -------------------------------------------------------------------------------- /zfast_lcd_hd.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | zfast_lcd_hd - A very simple LCD shader meant to be used at 1080p 3 | at arbitrary PPSSPP rendering resolutions 4 | 5 | Original code copyright (C) 2017 Greg Hogan (SoltanGris42) 6 | 7 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 2 of the License, or (at your option) 12 | any later version. 13 | 14 | Notes: This shader just applies a grid effect, darkening the borders of 15 | 'virtual' pixels at the native PSP resolution to imitate an LCD 16 | screen. You can change the darkness/thickness of the borders. 17 | 18 | While this shader works at arbritrary resolutions, the effect 19 | is not as pleasing as with the normal 'zfast_lcd' shader at 20 | native PSP resolution. This is due to the fact that we can't 21 | do nearest neighbour screen scaling in any meaningful fashion 22 | here, so the results are somewhat 'smudgy'... 23 | 24 | *** REQUIRES a display resolution of at least 1080p (otherwise grid 25 | effect will vanish...) 26 | */ 27 | 28 | 29 | //=== Config 30 | #define BORDERMULT 14.0 // "Border Multiplier" default: 14.0, min: -40.0, max: 40.0, step: 1.0 31 | 32 | //================ 33 | #ifdef GL_ES 34 | precision mediump float; 35 | precision mediump int; 36 | // For android, use this instead... 37 | //precision highp float; 38 | //precision highp int; 39 | // 40 | #endif 41 | 42 | //================ 43 | uniform sampler2D sampler0; 44 | uniform vec2 u_texelDelta; 45 | varying vec2 v_texcoord0; 46 | 47 | // Dirty hack: this should be called 'TextureSize', but when PPSSPP 48 | // performs shader translation it only coverts variables with a fixed 49 | // set of names - so in order for this shader to work with the Vulkan 50 | // backend, we have to 'borrow' one of the v_texcoord variables... 51 | // (note that we could work around this cleanly by calculating texture 52 | // size inside the fragment shader, but this would have a performance 53 | // impact and would therefore be lame...) 54 | varying vec2 v_texcoord1; // TextureSize 55 | 56 | //================ 57 | const float NATIVE_SCREEN_HEIGHT = 272.0; 58 | 59 | //================ 60 | void main() 61 | { 62 | // 63 | // Note to self: u_texelDelta.xy == 1 / TextureSize.xy 64 | // 65 | 66 | // Generate grid pattern (in native PSP coordinate space) 67 | vec2 texcoordInPixels = v_texcoord0.xy * v_texcoord1.xy * NATIVE_SCREEN_HEIGHT * u_texelDelta.y; // v_texcoord1 == TextureSize 68 | vec2 centerCoord = floor(texcoordInPixels.xy) + vec2(0.5, 0.5); 69 | vec2 distFromCenter = abs(centerCoord - texcoordInPixels); 70 | 71 | float Y = max(distFromCenter.x, distFromCenter.y); 72 | 73 | Y = Y * Y; 74 | float YY = Y * Y; 75 | float YYY = YY * Y; 76 | 77 | float LineWeight = YY - 2.7 * YYY; 78 | LineWeight = 1.0 - BORDERMULT * LineWeight; 79 | 80 | // Get colour sample and apply grid effect 81 | vec3 colour = texture2D(sampler0, v_texcoord0.xy).rgb * LineWeight; 82 | 83 | gl_FragColor = vec4(colour.rgb, 1.0); 84 | } 85 | -------------------------------------------------------------------------------- /zfast_lcd_hd_mobile.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | zfast_lcd_hd - A very simple LCD shader meant to be used at 1080p 3 | at arbitrary PPSSPP rendering resolutions 4 | 5 | Original code copyright (C) 2017 Greg Hogan (SoltanGris42) 6 | 7 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 8 | 9 | This program is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 2 of the License, or (at your option) 12 | any later version. 13 | 14 | Notes: This shader just applies a grid effect, darkening the borders of 15 | 'virtual' pixels at the native PSP resolution to imitate an LCD 16 | screen. You can change the darkness/thickness of the borders. 17 | 18 | While this shader works at arbritrary resolutions, the effect 19 | is not as pleasing as with the normal 'zfast_lcd' shader at 20 | native PSP resolution. This is due to the fact that we can't 21 | do nearest neighbour screen scaling in any meaningful fashion 22 | here, so the results are somewhat 'smudgy'... 23 | 24 | *** REQUIRES a display resolution of at least 1080p (otherwise grid 25 | effect will vanish...) 26 | */ 27 | 28 | 29 | //=== Config 30 | #define BORDERMULT 14.0 // "Border Multiplier" default: 14.0, min: -40.0, max: 40.0, step: 1.0 31 | 32 | //================ 33 | #ifdef GL_ES 34 | //precision mediump float; 35 | //precision mediump int; 36 | // For android, use this instead... 37 | precision highp float; 38 | precision highp int; 39 | #endif 40 | 41 | //================ 42 | uniform sampler2D sampler0; 43 | uniform vec2 u_texelDelta; 44 | varying vec2 v_texcoord0; 45 | 46 | // Dirty hack: this should be called 'TextureSize', but when PPSSPP 47 | // performs shader translation it only coverts variables with a fixed 48 | // set of names - so in order for this shader to work with the Vulkan 49 | // backend, we have to 'borrow' one of the v_texcoord variables... 50 | // (note that we could work around this cleanly by calculating texture 51 | // size inside the fragment shader, but this would have a performance 52 | // impact and would therefore be lame...) 53 | varying vec2 v_texcoord1; // TextureSize 54 | 55 | //================ 56 | const float NATIVE_SCREEN_HEIGHT = 272.0; 57 | 58 | //================ 59 | void main() 60 | { 61 | // 62 | // Note to self: u_texelDelta.xy == 1 / TextureSize.xy 63 | // 64 | 65 | // Generate grid pattern (in native PSP coordinate space) 66 | vec2 texcoordInPixels = v_texcoord0.xy * v_texcoord1.xy * NATIVE_SCREEN_HEIGHT * u_texelDelta.y; // v_texcoord1 == TextureSize 67 | vec2 centerCoord = floor(texcoordInPixels.xy) + vec2(0.5, 0.5); 68 | vec2 distFromCenter = abs(centerCoord - texcoordInPixels); 69 | 70 | float Y = max(distFromCenter.x, distFromCenter.y); 71 | 72 | Y = Y * Y; 73 | float YY = Y * Y; 74 | float YYY = YY * Y; 75 | 76 | float LineWeight = YY - 2.7 * YYY; 77 | LineWeight = 1.0 - BORDERMULT * LineWeight; 78 | 79 | // Get colour sample and apply grid effect 80 | vec3 colour = texture2D(sampler0, v_texcoord0.xy).rgb * LineWeight; 81 | 82 | gl_FragColor = vec4(colour.rgb, 1.0); 83 | } 84 | -------------------------------------------------------------------------------- /zfast_lcd_mobile.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | zfast_lcd - A very simple LCD shader meant to be used at 1080p 3 | 4 | Original code copyright (C) 2017 Greg Hogan (SoltanGris42) 5 | 6 | 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver 7 | 8 | This program is free software; you can redistribute it and/or modify it 9 | under the terms of the GNU General Public License as published by the Free 10 | Software Foundation; either version 2 of the License, or (at your option) 11 | any later version. 12 | 13 | Notes: This shader just does nearest neighbor scaling of the game and then 14 | darkens the border pixels to imitate an LCD screen. You can change 15 | the darkness/thickness of the borders. 16 | 17 | *** REQUIRES PPSSPP rendering resolution to be set to 1 x PSP 18 | 19 | *** REQUIRES a display resolution of at least 1080p (otherwise grid 20 | effect will vanish...) 21 | */ 22 | 23 | 24 | //=== Config 25 | #define BORDERMULT 14.0 // "Border Multiplier" default: 14.0, min: -40.0, max: 40.0, step: 1.0 26 | 27 | //================ 28 | #ifdef GL_ES 29 | //precision mediump float; 30 | //precision mediump int; 31 | // For android, use this instead... 32 | precision highp float; 33 | precision highp int; 34 | #endif 35 | 36 | //================ 37 | uniform sampler2D sampler0; 38 | uniform vec2 u_texelDelta; 39 | varying vec2 v_texcoord0; 40 | 41 | // Dirty hack: this should be called 'TextureSize', but when PPSSPP 42 | // performs shader translation it only coverts variables with a fixed 43 | // set of names - so in order for this shader to work with the Vulkan 44 | // backend, we have to 'borrow' one of the v_texcoord variables... 45 | // (note that we could work around this cleanly by calculating texture 46 | // size inside the fragment shader, but this would have a performance 47 | // impact and would therefore be lame...) 48 | varying vec2 v_texcoord1; // TextureSize 49 | 50 | //================ 51 | void main() 52 | { 53 | // 54 | // Note to self: u_texelDelta.xy == 1 / TextureSize.xy 55 | // 56 | 57 | // Generate grid pattern 58 | vec2 texcoordInPixels = v_texcoord0.xy * v_texcoord1.xy; // v_texcoord1 == TextureSize 59 | vec2 centerCoord = floor(texcoordInPixels.xy) + vec2(0.5, 0.5); 60 | vec2 distFromCenter = abs(centerCoord - texcoordInPixels); 61 | 62 | float Y = max(distFromCenter.x, distFromCenter.y); 63 | 64 | Y = Y * Y; 65 | float YY = Y * Y; 66 | float YYY = YY * Y; 67 | 68 | float LineWeight = YY - 2.7 * YYY; 69 | LineWeight = 1.0 - BORDERMULT * LineWeight; 70 | 71 | // Get colour sample and apply grid effect 72 | vec3 colour = texture2D(sampler0, u_texelDelta.xy * centerCoord).rgb * LineWeight; 73 | 74 | gl_FragColor = vec4(colour.rgb, 1.0); 75 | } 76 | --------------------------------------------------------------------------------