1#version 130
2
3/*
4	Scale2xSFX
5	by Sp00kyFox, 2015
6
7Filter:	Nearest
8Scale:	2x
9
10Scale2SFX improves upon the original Scale2x (aka EPX) by avoiding the occurence of artifacts.
11
12*/
13
14// Parameter lines go here:
15#pragma parameter YTR "SCALE2xSFX Y Threshold" 48.0 0.0 255.0 1.0
16#pragma parameter UTR "SCALE2xSFX U Threshold"  7.0 0.0 255.0 1.0
17#pragma parameter VTR "SCALE2xSFX V Threshold"  6.0 0.0 255.0 1.0
18
19#define saturate(c) clamp(c, 0.0, 1.0)
20#define lerp(a,b,c) mix(a,b,c)
21#define mul(a,b) (b*a)
22#define fmod(c,d) mod(c,d)
23#define frac(c) fract(c)
24#define tex2D(c,d) COMPAT_TEXTURE(c,d)
25#define float2 vec2
26#define float3 vec3
27#define float4 vec4
28#define int2 ivec2
29#define int3 ivec3
30#define int4 ivec4
31#define bool2 bvec2
32#define bool3 bvec3
33#define bool4 bvec4
34#define float2x2 mat2x2
35#define float3x3 mat3x3
36#define float4x4 mat4x4
37#define float4x3 mat4x3
38
39#define decal Source
40
41#if defined(VERTEX)
42
43#if __VERSION__ >= 130
44#define COMPAT_VARYING out
45#define COMPAT_ATTRIBUTE in
46#define COMPAT_TEXTURE texture
47#else
48#define COMPAT_VARYING varying
49#define COMPAT_ATTRIBUTE attribute
50#define COMPAT_TEXTURE texture2D
51#endif
52
53#ifdef GL_ES
54#define COMPAT_PRECISION mediump
55#else
56#define COMPAT_PRECISION
57#endif
58
59COMPAT_ATTRIBUTE vec4 VertexCoord;
60COMPAT_ATTRIBUTE vec4 COLOR;
61COMPAT_ATTRIBUTE vec4 TexCoord;
62COMPAT_VARYING vec4 COL0;
63COMPAT_VARYING vec4 TEX0;
64COMPAT_VARYING vec4 t1;
65COMPAT_VARYING vec4 t2;
66COMPAT_VARYING vec4 t3;
67COMPAT_VARYING vec4 t4;
68COMPAT_VARYING vec4 t5;
69
70uniform mat4 MVPMatrix;
71uniform COMPAT_PRECISION int FrameDirection;
72uniform COMPAT_PRECISION int FrameCount;
73uniform COMPAT_PRECISION vec2 OutputSize;
74uniform COMPAT_PRECISION vec2 TextureSize;
75uniform COMPAT_PRECISION vec2 InputSize;
76
77// vertex compatibility #defines
78#define vTexCoord TEX0.xy
79#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
80#define outsize vec4(OutputSize, 1.0 / OutputSize)
81
82void main()
83{
84    gl_Position = MVPMatrix * VertexCoord;
85    COL0 = COLOR;
86    TEX0.xy = TexCoord.xy;
87   	float2 ps = float2(SourceSize.z, SourceSize.w);
88	float dx = ps.x;
89	float dy = ps.y;
90
91	t1 = TEX0.xxxy + float4(-dx,  0., dx,-dy);	// A, B, C
92	t2 = TEX0.xxxy + float4(-dx,  0., dx,  0.);	// D, E, F
93	t3 = TEX0.xxxy + float4(-dx,  0., dx, dy);	// G, H, I
94	t4 = TEX0.xyxy + float4(    0.,-2.*dy,-2.*dx,    0.);	// J, K
95	t5 = TEX0.xyxy + float4( 2.*dx,    0.,    0., 2.*dy);	// L, M
96}
97
98#elif defined(FRAGMENT)
99
100#ifdef GL_ES
101#ifdef GL_FRAGMENT_PRECISION_HIGH
102precision highp float;
103#else
104precision mediump float;
105#endif
106#define COMPAT_PRECISION mediump
107#else
108#define COMPAT_PRECISION
109#endif
110
111#if __VERSION__ >= 130
112#define COMPAT_VARYING in
113#define COMPAT_TEXTURE texture
114out COMPAT_PRECISION vec4 FragColor;
115#else
116#define COMPAT_VARYING varying
117#define FragColor gl_FragColor
118#define COMPAT_TEXTURE texture2D
119#endif
120
121uniform COMPAT_PRECISION int FrameDirection;
122uniform COMPAT_PRECISION int FrameCount;
123uniform COMPAT_PRECISION vec2 OutputSize;
124uniform COMPAT_PRECISION vec2 TextureSize;
125uniform COMPAT_PRECISION vec2 InputSize;
126uniform sampler2D Texture;
127COMPAT_VARYING vec4 TEX0;
128COMPAT_VARYING vec4 t1;
129COMPAT_VARYING vec4 t2;
130COMPAT_VARYING vec4 t3;
131COMPAT_VARYING vec4 t4;
132COMPAT_VARYING vec4 t5;
133
134// fragment compatibility #defines
135#define Source Texture
136#define vTexCoord TEX0.xy
137
138#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
139#define outsize vec4(OutputSize, 1.0 / OutputSize)
140
141#ifdef PARAMETER_UNIFORM
142uniform COMPAT_PRECISION float YTR;
143uniform COMPAT_PRECISION float UTR;
144uniform COMPAT_PRECISION float VTR;
145#else
146#define YTR 48.0
147#define UTR 7.0
148#define VTR 6.0
149#endif
150
151mat3 YUV  = mat3(0.299, -0.168736, 0.5, 0.587, -0.331264, -0.418688, 0.114, 0.5, -0.081312);	// transponed
152float3 thresh = float3(0.188235294, 0.02745098, 0.023529412);
153
154bool eq(float3 A, float3 B){
155	return (A==B);
156}
157
158bool neq(float3 A, float3 B){
159	return (A!=B);
160}
161
162void main()
163{
164	// subpixel determination
165	float2 fp = floor(2.0 * frac(vTexCoord*SourceSize.xy));
166
167	/*
168		    J
169		  A B C		E0 E1
170		K D E F L	E2 E3
171		  G H I
172		    M
173	*/
174
175	// reading the texels & colorspace conversion
176	float3 b = tex2D(decal, t1.yw).xyz;
177	float3 d = tex2D(decal, t2.xw).xyz;
178	float3 e = tex2D(decal, t2.yw).xyz;
179	float3 f = tex2D(decal, t2.zw).xyz;
180	float3 h = tex2D(decal, t3.yw).xyz;
181
182	float4x3 tmp = mul(float4x3(b,d,e,f), YUV);
183	float3 B = tmp[0], D = tmp[1], E = tmp[2], F = tmp[3], H = mul(h, YUV);
184
185	float3 A = tex2D(decal, t1.xw).xyz;
186	float3 C = tex2D(decal, t1.zw).xyz;
187	float3 G = tex2D(decal, t3.xw).xyz;
188	float3 I = tex2D(decal, t3.zw).xyz;
189
190	tmp = mul(float4x3(A,C,G,I), YUV);
191	A = tmp[0], C = tmp[1], G = tmp[2], I = tmp[3];
192
193	float3 J = tex2D(decal, t4.xy).xyz;
194	float3 K = tex2D(decal, t4.zw).xyz;
195	float3 L = tex2D(decal, t5.xy).xyz;
196	float3 M = tex2D(decal, t5.zw).xyz;
197
198	tmp = mul(float4x3(J,K,L,M), YUV);
199	J = tmp[0], K = tmp[1], L = tmp[2], M = tmp[3];
200
201
202
203	// parent condition
204	bool par0 = neq(B,F) && neq(D,H);
205	bool par1 = neq(B,D) && neq(F,H);
206
207	// equality checks
208	bool AE = eq(A,E), CE = eq(C,E), EG = eq(E,G), EI = eq(E,I);
209
210	// artifact prevention
211	bool art0 = CE || EG;
212	bool art1 = AE || EI;
213
214
215
216	// rules
217	float3 E0 = eq(B,D) && par0 && (!AE || art0 || eq(A,J) || eq(A,K)) ? 0.5*(b+d) : e;
218	float3 E1 = eq(B,F) && par1 && (!CE || art1 || eq(C,J) || eq(C,L)) ? 0.5*(b+f) : e;
219	float3 E2 = eq(D,H) && par1 && (!EG || art1 || eq(G,K) || eq(G,M)) ? 0.5*(h+d) : e;
220	float3 E3 = eq(F,H) && par0 && (!EI || art0 || eq(I,L) || eq(I,M)) ? 0.5*(h+f) : e;
221
222	// subpixel output
223	FragColor = vec4(fp.y == 0. ? (fp.x == 0. ? E0 : E1) : (fp.x == 0. ? E2 : E3), 1.0);
224}
225#endif
226