123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- // This is a port of the original CG shader to the quark format
- // the original shader can be found here :
- // https://github.com/libretro/common-shaders/tree/master/handheld/gameboy
- ///////////////////////////////////////////////////////////////////////////
- // //
- // Gameboy Classic Shader v0.2.2 //
- // //
- // Copyright (C) 2013 Harlequin : unknown92835@gmail.com //
- // //
- // This program is free software: you can redistribute it and/or modify //
- // it under the terms of the GNU General Public License as published by //
- // the Free Software Foundation, either version 3 of the License, or //
- // (at your option) any later version. //
- // //
- // This program is distributed in the hope that it will be useful, //
- // but WITHOUT ANY WARRANTY; without even the implied warranty of //
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
- // GNU General Public License for more details. //
- // //
- // You should have received a copy of the GNU General Public License //
- // along with this program. If not, see <http://www.gnu.org/licenses/>. //
- // //
- ///////////////////////////////////////////////////////////////////////////
- #version 150
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //config //
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- #define baseline_alpha 0.10 //the alpha value of dots in their "off" state, does not affect the border region of the screen - [0, 1]
- #define response_time 0.333 //simulate response time, higher values result in longer color transition periods - [0, 1]
- //#define HIGAN_FORCE_MONOCHROME_GB //uncomment only when running gb games in higan since the shader expects black and white input.
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //fragment definitions //
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- #define foreground_color texture(pixmap[0], vec2(0.75, 0.5)).rgb //hardcoded to look up the foreground color from the right half of the palette image
- #define rgb_to_alpha(rgb) ( ((rgb.r + rgb.g + rgb.b) / 3.0) + (is_on_dot * baseline_alpha) ) //averages rgb values (allows it to work with color games), modified for contrast and base alpha
- #ifdef HIGAN_FORCE_MONOCHROME_GB
- #define TEX(src,coord) vec4(vec3(clamp(dot(texture(src, coord).rgb,vec3(21,-16.73,30)),0.0,1.0)),1.0)
- #else
- #define TEX(src,coord) texture(src, coord)
- #endif
- #define curr_rgb abs(1 - TEX(source[0], texCoord).rgb)
- #define prev0_rgb abs(1 - TEX(frame[0], texCoord).rgb)
- #define prev1_rgb abs(1 - TEX(frame[1], texCoord).rgb)
- #define prev2_rgb abs(1 - TEX(frame[2], texCoord).rgb)
- #define prev3_rgb abs(1 - TEX(frame[3], texCoord).rgb)
- #define prev4_rgb abs(1 - TEX(frame[4], texCoord).rgb)
- #define prev5_rgb abs(1 - TEX(frame[5], texCoord).rgb)
- #define prev6_rgb abs(1 - TEX(frame[6], texCoord).rgb)
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //fragment shader //
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- uniform sampler2D source[];
- uniform sampler2D frame[];
- uniform sampler2D pixmap[];
- uniform vec4 sourceSize[];
- uniform vec4 targetSize;
- in Vertex {
- vec2 texCoord;
- vec2 one_texel;
- };
- out vec4 fragColor;
- void main(void) {
- //determine if the corrent texel lies on a dot or in the space between dots
- float is_on_dot = float( mod(texCoord.x, sourceSize[0].z) > one_texel.x)* //returns 1 if fragment lies on a dot, 0 otherwise
- float(mod(texCoord.y, sourceSize[0].w) > one_texel.y )*
- float(texCoord.x>=0.0)*
- float(texCoord.x<=1.0)*
- float(texCoord.y>=0.0)*
- float(texCoord.y<=1.0);
- //sample color from the current and previous frames, apply response time modifier
- //response time effect implmented through an exponential dropoff algorithm
- vec3 input_rgb = curr_rgb;
- input_rgb += (prev0_rgb - input_rgb) * response_time;
- input_rgb += (prev1_rgb - input_rgb) * pow(response_time, 2.0);
- input_rgb += (prev2_rgb - input_rgb) * pow(response_time, 3.0);
- input_rgb += (prev3_rgb - input_rgb) * pow(response_time, 4.0);
- input_rgb += (prev4_rgb - input_rgb) * pow(response_time, 5.0);
- input_rgb += (prev5_rgb - input_rgb) * pow(response_time, 6.0);
- input_rgb += (prev6_rgb - input_rgb) * pow(response_time, 7.0);
- //apply foreground color and assign alpha value
- vec4 out_color = vec4(foreground_color, rgb_to_alpha(input_rgb)); //apply the foreground color to all texels (the color will be modified by alpha later) and assign alpha based on rgb input
-
- //overlay the matrix
- out_color.a *= is_on_dot; //if the fragment is not on a dot, set its alpha value to 0
- //return fragment color
- fragColor= out_color;
- }
|