all repos — mgba @ 7fd25804f50318da2d33ea8314d20df1c14a5587

mGBA Game Boy Advance Emulator

res/shaders/xbr-lv2.shader/xbr.fs (view raw)

  1/*
  2   Hyllian's xBR-lv2 Shader
  3   
  4   Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
  5
  6   Permission is hereby granted, free of charge, to any person obtaining a copy
  7   of this software and associated documentation files (the "Software"), to deal
  8   in the Software without restriction, including without limitation the rights
  9   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10   copies of the Software, and to permit persons to whom the Software is
 11   furnished to do so, subject to the following conditions:
 12
 13   The above copyright notice and this permission notice shall be included in
 14   all copies or substantial portions of the Software.
 15
 16   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 22   THE SOFTWARE.
 23
 24
 25   Incorporates some of the ideas from SABR shader. Thanks to Joshua Street.
 26*/
 27
 28uniform float XBR_Y_WEIGHT;
 29uniform float XBR_EQ_THRESHOLD;
 30uniform float XBR_SCALE;
 31uniform float XBR_LV2_COEFFICIENT;
 32
 33const vec4 Ao = vec4( 1.0, -1.0, -1.0, 1.0 );
 34const vec4 Bo = vec4( 1.0,  1.0, -1.0,-1.0 );
 35const vec4 Co = vec4( 1.5,  0.5, -0.5, 0.5 );
 36const vec4 Ax = vec4( 1.0, -1.0, -1.0, 1.0 );
 37const vec4 Bx = vec4( 0.5,  2.0, -0.5,-2.0 );
 38const vec4 Cx = vec4( 1.0,  1.0, -0.5, 0.0 );
 39const vec4 Ay = vec4( 1.0, -1.0, -1.0, 1.0 );
 40const vec4 By = vec4( 2.0,  0.5, -2.0,-0.5 );
 41const vec4 Cy = vec4( 2.0,  0.0, -1.0, 0.5 );
 42const vec4 Ci = vec4(0.25, 0.25, 0.25, 0.25);
 43
 44const vec3 Y = vec3(0.2126, 0.7152, 0.0722);
 45
 46vec4 df(vec4 A, vec4 B)
 47{
 48	return vec4(abs(A-B));
 49}
 50
 51float c_df(vec3 c1, vec3 c2) {
 52	vec3 df = abs(c1 - c2);
 53	return df.r + df.g + df.b;
 54}
 55
 56bvec4 eq(vec4 A, vec4 B)
 57{
 58	return lessThan(df(A, B), vec4(XBR_EQ_THRESHOLD));
 59}
 60
 61bvec4 and(bvec4 A, bvec4 B)
 62{
 63	return bvec4(A.x && B.x, A.y && B.y, A.z && B.z, A.w && B.w);
 64}
 65
 66bvec4 nand(bvec4 A, bvec4 B)
 67{
 68	return bvec4(!(A.x && B.x), !(A.y && B.y), !(A.z && B.z), !(A.w && B.w));
 69}
 70
 71bvec4 or(bvec4 A, bvec4 B)
 72{
 73	return bvec4(A.x || B.x, A.y || B.y, A.z || B.z, A.w || B.w);
 74}
 75
 76vec4 weighted_distance(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, vec4 h)
 77{
 78	return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + 4.0*df(g,h));
 79}
 80
 81// GLSL shader autogenerated by cg2glsl.py.
 82#if __VERSION__ >= 130
 83#define varying in
 84#define COMPAT_TEXTURE texture
 85out vec4 FragColor;
 86#else
 87#define FragColor gl_FragColor
 88#define COMPAT_TEXTURE texture2D
 89#endif
 90
 91#ifdef GL_ES
 92#ifdef GL_FRAGMENT_PRECISION_HIGH
 93precision highp float;
 94#else
 95precision mediump float;
 96#endif
 97#define COMPAT_PRECISION mediump
 98#else
 99#define COMPAT_PRECISION
100#endif
101uniform sampler2D tex;
102varying vec2 texCoord;
103varying vec4 TEX1;
104varying vec4 TEX2;
105varying vec4 TEX3;
106varying vec4 TEX4;
107varying vec4 TEX5;
108varying vec4 TEX6;
109varying vec4 TEX7;
110
111uniform vec2 texSize;
112
113void main()
114{
115	bvec4 edri, edr, edr_left, edr_up; // px = pixel, edr = edge detection rule
116	bvec4 interp_restriction_lv0, interp_restriction_lv1, interp_restriction_lv2_left, interp_restriction_lv2_up;
117	vec4 fx, fx_left, fx_up, px; // inequations of straight lines.
118
119	vec4 delta = vec4(1.0 / XBR_SCALE);
120	vec4 deltaL = vec4(0.5/ XBR_SCALE, 1.0 / XBR_SCALE, 0.5 / XBR_SCALE, 1.0 / XBR_SCALE);
121	vec4 deltaU = deltaL.yxwz;
122
123    vec2 fp = fract(texCoord * texSize);
124
125    vec3 A1 = COMPAT_TEXTURE(tex, TEX1.xw).rgb;
126    vec3 B1 = COMPAT_TEXTURE(tex, TEX1.yw).rgb;
127    vec3 C1 = COMPAT_TEXTURE(tex, TEX1.zw).rgb;
128
129    vec3 A = COMPAT_TEXTURE(tex, TEX2.xw).rgb;
130    vec3 B = COMPAT_TEXTURE(tex, TEX2.yw).rgb;
131    vec3 C = COMPAT_TEXTURE(tex, TEX2.zw).rgb;
132
133    vec3 D = COMPAT_TEXTURE(tex, TEX3.xw).rgb;
134    vec3 E = COMPAT_TEXTURE(tex, TEX3.yw).rgb;
135    vec3 F = COMPAT_TEXTURE(tex, TEX3.zw).rgb;
136
137    vec3 G = COMPAT_TEXTURE(tex, TEX4.xw).rgb;
138    vec3 H = COMPAT_TEXTURE(tex, TEX4.yw).rgb;
139    vec3 I = COMPAT_TEXTURE(tex, TEX4.zw).rgb;
140
141    vec3 G5 = COMPAT_TEXTURE(tex, TEX5.xw).rgb;
142    vec3 H5 = COMPAT_TEXTURE(tex, TEX5.yw).rgb;
143    vec3 I5 = COMPAT_TEXTURE(tex, TEX5.zw).rgb;
144
145    vec3 A0 = COMPAT_TEXTURE(tex, TEX6.xy).rgb;
146    vec3 D0 = COMPAT_TEXTURE(tex, TEX6.xz).rgb;
147    vec3 G0 = COMPAT_TEXTURE(tex, TEX6.xw).rgb;
148
149    vec3 C4 = COMPAT_TEXTURE(tex, TEX7.xy).rgb;
150    vec3 F4 = COMPAT_TEXTURE(tex, TEX7.xz).rgb;
151    vec3 I4 = COMPAT_TEXTURE(tex, TEX7.xw).rgb;
152
153	vec4 b = transpose(mat4x3(B, D, H, F)) * (XBR_Y_WEIGHT * Y);
154	vec4 c = transpose(mat4x3(C, A, G, I)) * (XBR_Y_WEIGHT * Y);
155	vec4 e = transpose(mat4x3(E, E, E, E)) * (XBR_Y_WEIGHT * Y);
156	vec4 d = b.yzwx;
157	vec4 f = b.wxyz;
158	vec4 g = c.zwxy;
159	vec4 h = b.zwxy;
160	vec4 i = c.wxyz;
161
162	vec4 i4 = transpose(mat4x3(I4, C1, A0, G5)) * (XBR_Y_WEIGHT * Y);
163	vec4 i5 = transpose(mat4x3(I5, C4, A1, G0)) * (XBR_Y_WEIGHT * Y);
164	vec4 h5 = transpose(mat4x3(H5, F4, B1, D0)) * (XBR_Y_WEIGHT * Y);
165	vec4 f4 = h5.yzwx;
166
167	fx      = (Ao*fp.y+Bo*fp.x);
168	fx_left = (Ax*fp.y+Bx*fp.x);
169	fx_up   = (Ay*fp.y+By*fp.x);
170
171	interp_restriction_lv1 = interp_restriction_lv0 = and(notEqual(e, f), notEqual(e, h));
172
173    interp_restriction_lv2_left = and(notEqual(e, g), notEqual(d, g));
174	interp_restriction_lv2_up   = and(notEqual(e, c), notEqual(b, c));
175
176	vec4 fx45i = clamp((fx      + delta  - Co - Ci) / (2 * delta ), 0.0, 1.0);
177	vec4 fx45  = clamp((fx      + delta  - Co     ) / (2 * delta ), 0.0, 1.0);
178	vec4 fx30  = clamp((fx_left + deltaL - Co     ) / (2 * deltaL), 0.0, 1.0);
179	vec4 fx60  = clamp((fx_up   + deltaU - Co     ) / (2 * deltaU), 0.0, 1.0);
180
181	vec4 wd1 = weighted_distance( e, c, g, i, h5, f4, h, f);
182	vec4 wd2 = weighted_distance( h, d, i5, f, i4, b, e, i);
183
184	edri = and(lessThanEqual(wd1, wd2), interp_restriction_lv0);
185	edr  = and(     lessThan(wd1, wd2), interp_restriction_lv1);
186
187	edr_left = and(lessThanEqual((XBR_LV2_COEFFICIENT*df(f,g)), df(h,c)), interp_restriction_lv2_left);
188	edr_up   = and(greaterThanEqual(df(f,g), (XBR_LV2_COEFFICIENT*df(h,c))), interp_restriction_lv2_up);
189
190	edr = and(edr, nand(edri.yzwx, edri.wxyz));
191	edr_left = and(and(edr_left, edr), eq(e, c));
192	edr_up = and(and(edr_up, edr), eq(e, g));
193
194	fx45  *= vec4(edr);
195	fx30  *= vec4(edr_left);
196	fx60  *= vec4(edr_up);
197	fx45i *= vec4(edri);
198
199    px = vec4(lessThanEqual(df(e, f), df(e, h)));
200
201	vec4 maximos = max(max(fx30, fx60), max(fx45, fx45i));
202
203	vec3 res1 = E;
204	res1 = mix(res1, mix(H, F, px.x), maximos.x);
205	res1 = mix(res1, mix(B, D, px.z), maximos.z);
206
207	vec3 res2 = E;
208	res2 = mix(res1, mix(F, B, px.y), maximos.y);
209	res2 = mix(res1, mix(D, H, px.w), maximos.w);
210
211    vec3 res = mix(res1, res2, step(c_df(E, res1), c_df(E, res2)));
212
213    FragColor = vec4(res, 1.0);
214}