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}