1///////////////////////////////////////////////////////////////////////////
2//                                                                       //
3// Gameboy Classic Shader v0.2.2                                         //
4//                                                                       //
5// Copyright (C) 2013 Harlequin : unknown92835@gmail.com                 //
6//                                                                       //
7// This program is free software: you can redistribute it and/or modify  //
8// it under the terms of the GNU General Public License as published by  //
9// the Free Software Foundation, either version 3 of the License, or     //
10// (at your option) any later version.                                   //
11//                                                                       //
12// This program is distributed in the hope that it will be useful,       //
13// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
15// GNU General Public License for more details.                          //
16//                                                                       //
17// You should have received a copy of the GNU General Public License     //
18// along with this program.  If not, see <http://www.gnu.org/licenses/>. //
19//                                                                       //
20///////////////////////////////////////////////////////////////////////////
21
22////////////////////////////////////////////////////////////////////////////////
23// Config                                                                     //
24////////////////////////////////////////////////////////////////////////////////
25
26// Useful to fine-tune the colors.
27// Higher values make the "black" color closer to black - [0, 1] [DEFAULT: 0.95]
28#pragma parameter contrast "Contrast" 0.70 0.0 1.0 0.05
29
30// Controls the ambient light of the screen.
31// Lower values darken the screen - [0, 2] [DEFAULT: 1.00]
32#pragma parameter screen_light "Ambient Screen Light" 0.85 0.0 2.0 0.05
33
34// Controls the opacity of the dot-matrix pixels.
35// Lower values make pixels more transparent - [0, 1] [DEFAULT: 1.00]
36#pragma parameter pixel_opacity "Pixel Opacity" 0.9 0.01 1.0 0.01
37
38// Higher values suppress changes in background color directly beneath
39// the foreground to improve image clarity - [0, 1] [DEFAULT: 0.75]
40#pragma parameter bg_smoothing "Background Smooth" 0.0 0.0 1.0 0.05
41
42// How strongly shadows affect the background
43// Higher values darken the shadows - [0, 1] [DEFAULT: 0.55]
44#pragma parameter shadow_opacity "Shadow Opacity" 0.90 0.01 1.0 0.01
45
46// How far the shadow should be shifted to the
47// right in pixels - [-infinity, infinity] [DEFAULT: 1.0]
48#pragma parameter shadow_offset_x "Shadow Offset Horiz" -1.5 -5.0 5.0 0.5
49
50// How far the shadow should be shifted
51// down in pixels - [-infinity, infinity] [DEFAULT: 1.5]
52#pragma parameter shadow_offset_y "Shadow Offset Vert" 1.5 -5.0 5.0 0.5
53
54// Screen offset - [-infinity, infinity] [DEFAULT: 0]
55#pragma parameter screen_offset_x "Screen Offset Horiz" 0.0 -5.0 5.0 0.5
56
57// Screen offset - [-infinity, infinity] [DEFAULT: 0]
58#pragma parameter screen_offset_y "Screen Offset Vert" 0.0 -5.0 5.0 0.5
59
60#if defined(VERTEX)
61
62#if __VERSION__ >= 130
63#define COMPAT_VARYING out
64#define COMPAT_ATTRIBUTE in
65#define COMPAT_TEXTURE texture
66#else
67#define COMPAT_VARYING varying
68#define COMPAT_ATTRIBUTE attribute
69#define COMPAT_TEXTURE texture2D
70#endif
71
72#ifdef GL_ES
73#define COMPAT_PRECISION mediump
74#else
75#define COMPAT_PRECISION
76#endif
77
78COMPAT_ATTRIBUTE vec4 VertexCoord;
79COMPAT_ATTRIBUTE vec4 COLOR;
80COMPAT_ATTRIBUTE vec4 TexCoord;
81COMPAT_VARYING vec4 COL0;
82COMPAT_VARYING vec4 TEX0;
83COMPAT_VARYING vec2 texel;
84
85vec4 _oPosition1;
86uniform mat4 MVPMatrix;
87uniform COMPAT_PRECISION int FrameDirection;
88uniform COMPAT_PRECISION int FrameCount;
89uniform COMPAT_PRECISION vec2 OutputSize;
90uniform COMPAT_PRECISION vec2 TextureSize;
91uniform COMPAT_PRECISION vec2 InputSize;
92
93#define vTexCoord TEX0.xy
94#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
95#define outsize vec4(OutputSize, 1.0 / OutputSize)
96
97void main()
98{
99    gl_Position = MVPMatrix * VertexCoord;
100    COL0 = COLOR;
101    TEX0.xy = TexCoord.xy;
102    texel = SourceSize.zw;
103}
104
105#elif defined(FRAGMENT)
106////////////////////////////////////////////////////////////////////////////////
107// Fragment shader                                                            //
108////////////////////////////////////////////////////////////////////////////////
109
110#if __VERSION__ >= 130
111#define COMPAT_VARYING in
112#define COMPAT_TEXTURE texture
113out vec4 FragColor;
114#else
115#define COMPAT_VARYING varying
116#define FragColor gl_FragColor
117#define COMPAT_TEXTURE texture2D
118#endif
119
120#ifdef GL_ES
121#ifdef GL_FRAGMENT_PRECISION_HIGH
122precision highp float;
123#else
124precision mediump float;
125#endif
126#define COMPAT_PRECISION mediump
127#else
128#define COMPAT_PRECISION
129#endif
130
131uniform COMPAT_PRECISION int FrameDirection;
132uniform COMPAT_PRECISION int FrameCount;
133uniform COMPAT_PRECISION vec2 OutputSize;
134uniform COMPAT_PRECISION vec2 TextureSize;
135uniform COMPAT_PRECISION vec2 InputSize;
136uniform sampler2D Texture;
137uniform sampler2D BACKGROUND;
138uniform sampler2D COLOR_PALETTE;
139uniform sampler2D Pass2Texture;
140COMPAT_VARYING vec4 TEX0;
141COMPAT_VARYING vec2 texel;
142
143////////////////////////////////////////////////////////////////////////////////
144// Fragment definitions                                                       //
145////////////////////////////////////////////////////////////////////////////////
146// compatibility #defines
147#define Source Texture
148#define vTexCoord TEX0.xy
149
150#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
151#define outsize vec4(OutputSize, 1.0 / OutputSize)
152
153#ifdef PARAMETER_UNIFORM
154// All parameter floats need to have COMPAT_PRECISION in front of them
155uniform COMPAT_PRECISION float contrast;
156uniform COMPAT_PRECISION float screen_light;
157uniform COMPAT_PRECISION float pixel_opacity;
158uniform COMPAT_PRECISION float bg_smoothing;
159uniform COMPAT_PRECISION float shadow_opacity;
160uniform COMPAT_PRECISION float shadow_offset_x;
161uniform COMPAT_PRECISION float shadow_offset_y;
162uniform COMPAT_PRECISION float screen_offset_x;
163uniform COMPAT_PRECISION float screen_offset_y;
164#else
165#define contrast 0.95
166#define screen_light 1.0
167#define pixel_opacity 1.0
168#define bg_smoothing 0.75
169#define shadow_opacity 0.55
170#define shadow_offset_x 1.0
171#define shadow_offset_y 1.0
172#define screen_offset_x 0.0
173#define screen_offset_y 0.0
174#endif
175
176#define bg_color COMPAT_TEXTURE(COLOR_PALETTE, vec2(0.25, 0.5))
177
178// Sample the background color from the palette
179#define shadow_alpha (contrast * shadow_opacity)
180
181// Offset for the shadow
182#define shadow_offset vec2(shadow_offset_x * texel.x, shadow_offset_y * texel.y)
183
184// Offset for the entire screen
185#define screen_offset vec2(screen_offset_x * texel.x, screen_offset_y * texel.y)
186
187void main()
188{
189//    vec2 tex = floor(outsize.xy * vTexCoord);
190//    tex = (tex + 0.5) * outsize.zw;
191    vec2 tex = vTexCoord.xy;
192
193    // Sample all the relevant textures
194    vec4 foreground = COMPAT_TEXTURE(Pass2Texture, tex - screen_offset);
195    vec4 background = COMPAT_TEXTURE(BACKGROUND, vTexCoord);
196    vec4 shadows    = COMPAT_TEXTURE(Source, vTexCoord - (shadow_offset + screen_offset));
197    vec4 background_color = bg_color;
198
199    // Foreground and background are blended with the background color
200    foreground *= 1.0;
201
202    background -= (background - 0.5) * bg_smoothing * float(foreground.a > 0.0); //suppress drastic background color changes under the foreground to improve clarity
203
204    // Allows for highlights,
205    // background = bg_color when the background color is 0.5 gray
206    background.rgb = clamp(
207        vec3(
208            bg_color.r + mix(-1.0, 1.0, background.r),
209            bg_color.g + mix(-1.0, 1.0, background.g),
210            bg_color.b + mix(-1.0, 1.0, background.b)
211        ),
212        0.0, 1.0
213    );
214
215    // Shadows are alpha blended with the background
216    vec4 out_color = (shadows * shadows.a * shadow_alpha) + (background * (1.0 - shadows.a * shadow_alpha));
217
218    // Foreground is alpha blended with the shadowed background
219    out_color = (foreground * foreground.a * (1.0 - foreground.a * foreground.a * contrast))
220		+ (out_color * (screen_light - foreground.a * contrast * pixel_opacity));
221
222    FragColor = out_color;
223}
224#endif
225