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