1/* 2 Hyllian's xBR-vertex code and texel mapping 3 4 Copyright (C) 2011/2016 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 26// This shader also uses code and/or concepts from xBRZ as it appears 27// in the Desmume source code. The license for which is as follows: 28 29// **************************************************************************** 30// * This file is part of the HqMAME project. It is distributed under * 31// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 * 32// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved * 33// * * 34// * Additionally and as a special exception, the author gives permission * 35// * to link the code of this program with the MAME library (or with modified * 36// * versions of MAME that use the same license as MAME), and distribute * 37// * linked combinations including the two. You must obey the GNU General * 38// * Public License in all respects for all of the code used other than MAME. * 39// * If you modify this file, you may extend this exception to your version * 40// * of the file, but you are not obligated to do so. If you do not wish to * 41// * do so, delete this exception statement from your version. * 42// **************************************************************************** 43 44#define BLEND_NONE 0 45#define BLEND_NORMAL 1 46#define BLEND_DOMINANT 2 47#define LUMINANCE_WEIGHT 1.0 48#define EQUAL_COLOR_TOLERANCE 30.0/255.0 49#define STEEP_DIRECTION_THRESHOLD 2.2 50#define DOMINANT_DIRECTION_THRESHOLD 3.6 51 52#if defined(VERTEX) 53 54#if __VERSION__ >= 130 55#define COMPAT_VARYING out 56#define COMPAT_ATTRIBUTE in 57#define COMPAT_TEXTURE texture 58#else 59#define COMPAT_VARYING varying 60#define COMPAT_ATTRIBUTE attribute 61#define COMPAT_TEXTURE texture2D 62#endif 63 64#ifdef GL_ES 65#define COMPAT_PRECISION mediump 66#else 67#define COMPAT_PRECISION 68#endif 69 70COMPAT_ATTRIBUTE vec4 VertexCoord; 71COMPAT_ATTRIBUTE vec4 COLOR; 72COMPAT_ATTRIBUTE vec4 TexCoord; 73COMPAT_VARYING vec4 COL0; 74COMPAT_VARYING vec4 TEX0; 75COMPAT_VARYING vec4 t1; 76COMPAT_VARYING vec4 t2; 77COMPAT_VARYING vec4 t3; 78COMPAT_VARYING vec4 t4; 79COMPAT_VARYING vec4 t5; 80COMPAT_VARYING vec4 t6; 81COMPAT_VARYING vec4 t7; 82 83uniform mat4 MVPMatrix; 84uniform COMPAT_PRECISION int FrameDirection; 85uniform COMPAT_PRECISION int FrameCount; 86uniform COMPAT_PRECISION vec2 OutputSize; 87uniform COMPAT_PRECISION vec2 TextureSize; 88uniform COMPAT_PRECISION vec2 InputSize; 89 90// vertex compatibility #defines 91#define vTexCoord TEX0.xy 92#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize 93#define outsize vec4(OutputSize, 1.0 / OutputSize) 94 95void main() 96{ 97 gl_Position = MVPMatrix * VertexCoord; 98 COL0 = COLOR; 99 TEX0.xy = TexCoord.xy; 100 vec2 ps = vec2(SourceSize.z, SourceSize.w); 101 float dx = ps.x; 102 float dy = ps.y; 103 104 // A1 B1 C1 105 // A0 A B C C4 106 // D0 D E F F4 107 // G0 G H I I4 108 // G5 H5 I5 109 110 t1 = vTexCoord.xxxy + vec4( -dx, 0.0, dx,-2.0*dy); // A1 B1 C1 111 t2 = vTexCoord.xxxy + vec4( -dx, 0.0, dx, -dy); // A B C 112 t3 = vTexCoord.xxxy + vec4( -dx, 0.0, dx, 0.0); // D E F 113 t4 = vTexCoord.xxxy + vec4( -dx, 0.0, dx, dy); // G H I 114 t5 = vTexCoord.xxxy + vec4( -dx, 0.0, dx, 2.0*dy); // G5 H5 I5 115 t6 = vTexCoord.xyyy + vec4(-2.0*dx,-dy, 0.0, dy); // A0 D0 G0 116 t7 = vTexCoord.xyyy + vec4( 2.0*dx,-dy, 0.0, dy); // C4 F4 I4 117} 118 119#elif defined(FRAGMENT) 120 121#if __VERSION__ >= 130 122#define COMPAT_VARYING in 123#define COMPAT_TEXTURE texture 124out vec4 FragColor; 125#else 126#define COMPAT_VARYING varying 127#define FragColor gl_FragColor 128#define COMPAT_TEXTURE texture2D 129#endif 130 131#ifdef GL_ES 132#ifdef GL_FRAGMENT_PRECISION_HIGH 133precision highp float; 134#else 135precision mediump float; 136#endif 137#define COMPAT_PRECISION mediump 138#else 139#define COMPAT_PRECISION 140#endif 141 142uniform COMPAT_PRECISION int FrameDirection; 143uniform COMPAT_PRECISION int FrameCount; 144uniform COMPAT_PRECISION vec2 OutputSize; 145uniform COMPAT_PRECISION vec2 TextureSize; 146uniform COMPAT_PRECISION vec2 InputSize; 147uniform sampler2D Texture; 148COMPAT_VARYING vec4 TEX0; 149COMPAT_VARYING vec4 t1; 150COMPAT_VARYING vec4 t2; 151COMPAT_VARYING vec4 t3; 152COMPAT_VARYING vec4 t4; 153COMPAT_VARYING vec4 t5; 154COMPAT_VARYING vec4 t6; 155COMPAT_VARYING vec4 t7; 156 157// fragment compatibility #defines 158#define Source Texture 159#define vTexCoord TEX0.xy 160 161#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize 162#define outsize vec4(OutputSize, 1.0 / OutputSize) 163 164 const float one_sixth = 1.0 / 6.0; 165 const float two_sixth = 2.0 / 6.0; 166 const float four_sixth = 4.0 / 6.0; 167 const float five_sixth = 5.0 / 6.0; 168 169 float reduce(const vec3 color) 170 { 171 return dot(color, vec3(65536.0, 256.0, 1.0)); 172 } 173 174 float DistYCbCr(const vec3 pixA, const vec3 pixB) 175 { 176 const vec3 w = vec3(0.2627, 0.6780, 0.0593); 177 const float scaleB = 0.5 / (1.0 - w.b); 178 const float scaleR = 0.5 / (1.0 - w.r); 179 vec3 diff = pixA - pixB; 180 float Y = dot(diff, w); 181 float Cb = scaleB * (diff.b - Y); 182 float Cr = scaleR * (diff.r - Y); 183 184 return sqrt( ((LUMINANCE_WEIGHT * Y) * (LUMINANCE_WEIGHT * Y)) + (Cb * Cb) + (Cr * Cr) ); 185 } 186 187 bool IsPixEqual(const vec3 pixA, const vec3 pixB) 188 { 189 return (DistYCbCr(pixA, pixB) < EQUAL_COLOR_TOLERANCE); 190 } 191 192 bool IsBlendingNeeded(const ivec4 blend) 193 { 194 return any(notEqual(blend, ivec4(BLEND_NONE))); 195 } 196 197 //--------------------------------------- 198 // Input Pixel Mapping: --|21|22|23|-- 199 // 19|06|07|08|09 200 // 18|05|00|01|10 201 // 17|04|03|02|11 202 // --|15|14|13|-- 203 // 204 // Output Pixel Mapping: 20|21|22|23|24|25 205 // 19|06|07|08|09|26 206 // 18|05|00|01|10|27 207 // 17|04|03|02|11|28 208 // 16|15|14|13|12|29 209 // 35|34|33|32|31|30 210 211void main() 212{ 213vec2 f = fract(vTexCoord.xy * SourceSize.xy); 214 215 //--------------------------------------- 216 // Input Pixel Mapping: 20|21|22|23|24 217 // 19|06|07|08|09 218 // 18|05|00|01|10 219 // 17|04|03|02|11 220 // 16|15|14|13|12 221 222 vec3 src[25]; 223 224 src[21] = COMPAT_TEXTURE(Source, t1.xw).rgb; 225 src[22] = COMPAT_TEXTURE(Source, t1.yw).rgb; 226 src[23] = COMPAT_TEXTURE(Source, t1.zw).rgb; 227 src[ 6] = COMPAT_TEXTURE(Source, t2.xw).rgb; 228 src[ 7] = COMPAT_TEXTURE(Source, t2.yw).rgb; 229 src[ 8] = COMPAT_TEXTURE(Source, t2.zw).rgb; 230 src[ 5] = COMPAT_TEXTURE(Source, t3.xw).rgb; 231 src[ 0] = COMPAT_TEXTURE(Source, t3.yw).rgb; 232 src[ 1] = COMPAT_TEXTURE(Source, t3.zw).rgb; 233 src[ 4] = COMPAT_TEXTURE(Source, t4.xw).rgb; 234 src[ 3] = COMPAT_TEXTURE(Source, t4.yw).rgb; 235 src[ 2] = COMPAT_TEXTURE(Source, t4.zw).rgb; 236 src[15] = COMPAT_TEXTURE(Source, t5.xw).rgb; 237 src[14] = COMPAT_TEXTURE(Source, t5.yw).rgb; 238 src[13] = COMPAT_TEXTURE(Source, t5.zw).rgb; 239 src[19] = COMPAT_TEXTURE(Source, t6.xy).rgb; 240 src[18] = COMPAT_TEXTURE(Source, t6.xz).rgb; 241 src[17] = COMPAT_TEXTURE(Source, t6.xw).rgb; 242 src[ 9] = COMPAT_TEXTURE(Source, t7.xy).rgb; 243 src[10] = COMPAT_TEXTURE(Source, t7.xz).rgb; 244 src[11] = COMPAT_TEXTURE(Source, t7.xw).rgb; 245 246 float v[9]; 247 v[0] = reduce(src[0]); 248 v[1] = reduce(src[1]); 249 v[2] = reduce(src[2]); 250 v[3] = reduce(src[3]); 251 v[4] = reduce(src[4]); 252 v[5] = reduce(src[5]); 253 v[6] = reduce(src[6]); 254 v[7] = reduce(src[7]); 255 v[8] = reduce(src[8]); 256 257 ivec4 blendResult = ivec4(BLEND_NONE); 258 259 // Preprocess corners 260 // Pixel Tap Mapping: --|--|--|--|-- 261 // --|--|07|08|-- 262 // --|05|00|01|10 263 // --|04|03|02|11 264 // --|--|14|13|-- 265 // Corner (1, 1) 266 if ( ((v[0] == v[1] && v[3] == v[2]) || (v[0] == v[3] && v[1] == v[2])) == false) 267 { 268 float dist_03_01 = DistYCbCr(src[ 4], src[ 0]) + DistYCbCr(src[ 0], src[ 8]) + DistYCbCr(src[14], src[ 2]) + DistYCbCr(src[ 2], src[10]) + (4.0 * DistYCbCr(src[ 3], src[ 1])); 269 float dist_00_02 = DistYCbCr(src[ 5], src[ 3]) + DistYCbCr(src[ 3], src[13]) + DistYCbCr(src[ 7], src[ 1]) + DistYCbCr(src[ 1], src[11]) + (4.0 * DistYCbCr(src[ 0], src[ 2])); 270 bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_03_01) < dist_00_02; 271 blendResult[2] = ((dist_03_01 < dist_00_02) && (v[0] != v[1]) && (v[0] != v[3])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; 272 } 273 274 // Pixel Tap Mapping: --|--|--|--|-- 275 // --|06|07|--|-- 276 // 18|05|00|01|-- 277 // 17|04|03|02|-- 278 // --|15|14|--|-- 279 // Corner (0, 1) 280 if ( ((v[5] == v[0] && v[4] == v[3]) || (v[5] == v[4] && v[0] == v[3])) == false) 281 { 282 float dist_04_00 = DistYCbCr(src[17], src[ 5]) + DistYCbCr(src[ 5], src[ 7]) + DistYCbCr(src[15], src[ 3]) + DistYCbCr(src[ 3], src[ 1]) + (4.0 * DistYCbCr(src[ 4], src[ 0])); 283 float dist_05_03 = DistYCbCr(src[18], src[ 4]) + DistYCbCr(src[ 4], src[14]) + DistYCbCr(src[ 6], src[ 0]) + DistYCbCr(src[ 0], src[ 2]) + (4.0 * DistYCbCr(src[ 5], src[ 3])); 284 bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_05_03) < dist_04_00; 285 blendResult[3] = ((dist_04_00 > dist_05_03) && (v[0] != v[5]) && (v[0] != v[3])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; 286 } 287 288 // Pixel Tap Mapping: --|--|22|23|-- 289 // --|06|07|08|09 290 // --|05|00|01|10 291 // --|--|03|02|-- 292 // --|--|--|--|-- 293 // Corner (1, 0) 294 if ( ((v[7] == v[8] && v[0] == v[1]) || (v[7] == v[0] && v[8] == v[1])) == false) 295 { 296 float dist_00_08 = DistYCbCr(src[ 5], src[ 7]) + DistYCbCr(src[ 7], src[23]) + DistYCbCr(src[ 3], src[ 1]) + DistYCbCr(src[ 1], src[ 9]) + (4.0 * DistYCbCr(src[ 0], src[ 8])); 297 float dist_07_01 = DistYCbCr(src[ 6], src[ 0]) + DistYCbCr(src[ 0], src[ 2]) + DistYCbCr(src[22], src[ 8]) + DistYCbCr(src[ 8], src[10]) + (4.0 * DistYCbCr(src[ 7], src[ 1])); 298 bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_07_01) < dist_00_08; 299 blendResult[1] = ((dist_00_08 > dist_07_01) && (v[0] != v[7]) && (v[0] != v[1])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; 300 } 301 302 // Pixel Tap Mapping: --|21|22|--|-- 303 // 19|06|07|08|-- 304 // 18|05|00|01|-- 305 // --|04|03|--|-- 306 // --|--|--|--|-- 307 // Corner (0, 0) 308 if ( ((v[6] == v[7] && v[5] == v[0]) || (v[6] == v[5] && v[7] == v[0])) == false) 309 { 310 float dist_05_07 = DistYCbCr(src[18], src[ 6]) + DistYCbCr(src[ 6], src[22]) + DistYCbCr(src[ 4], src[ 0]) + DistYCbCr(src[ 0], src[ 8]) + (4.0 * DistYCbCr(src[ 5], src[ 7])); 311 float dist_06_00 = DistYCbCr(src[19], src[ 5]) + DistYCbCr(src[ 5], src[ 3]) + DistYCbCr(src[21], src[ 7]) + DistYCbCr(src[ 7], src[ 1]) + (4.0 * DistYCbCr(src[ 6], src[ 0])); 312 bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_05_07) < dist_06_00; 313 blendResult[0] = ((dist_05_07 < dist_06_00) && (v[0] != v[5]) && (v[0] != v[7])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; 314 } 315 316 vec3 dst[36]; 317 dst[ 0] = src[0]; 318 dst[ 1] = src[0]; 319 dst[ 2] = src[0]; 320 dst[ 3] = src[0]; 321 dst[ 4] = src[0]; 322 dst[ 5] = src[0]; 323 dst[ 6] = src[0]; 324 dst[ 7] = src[0]; 325 dst[ 8] = src[0]; 326 dst[ 9] = src[0]; 327 dst[10] = src[0]; 328 dst[11] = src[0]; 329 dst[12] = src[0]; 330 dst[13] = src[0]; 331 dst[14] = src[0]; 332 dst[15] = src[0]; 333 dst[16] = src[0]; 334 dst[17] = src[0]; 335 dst[18] = src[0]; 336 dst[19] = src[0]; 337 dst[20] = src[0]; 338 dst[21] = src[0]; 339 dst[22] = src[0]; 340 dst[23] = src[0]; 341 dst[24] = src[0]; 342 dst[25] = src[0]; 343 dst[26] = src[0]; 344 dst[27] = src[0]; 345 dst[28] = src[0]; 346 dst[29] = src[0]; 347 dst[30] = src[0]; 348 dst[31] = src[0]; 349 dst[32] = src[0]; 350 dst[33] = src[0]; 351 dst[34] = src[0]; 352 dst[35] = src[0]; 353 354 // Scale pixel 355 if (IsBlendingNeeded(blendResult) == true) 356 { 357 float dist_01_04 = DistYCbCr(src[1], src[4]); 358 float dist_03_08 = DistYCbCr(src[3], src[8]); 359 bool haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[4]) && (v[5] != v[4]); 360 bool haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[8]) && (v[7] != v[8]); 361 bool needBlend = (blendResult[2] != BLEND_NONE); 362 bool doLineBlend = ( blendResult[2] >= BLEND_DOMINANT || 363 ((blendResult[1] != BLEND_NONE && !IsPixEqual(src[0], src[4])) || 364 (blendResult[3] != BLEND_NONE && !IsPixEqual(src[0], src[8])) || 365 (IsPixEqual(src[4], src[3]) && IsPixEqual(src[3], src[2]) && IsPixEqual(src[2], src[1]) && IsPixEqual(src[1], src[8]) && IsPixEqual(src[0], src[2]) == false) ) == false ); 366 367 vec3 blendPix = ( DistYCbCr(src[0], src[1]) <= DistYCbCr(src[0], src[3]) ) ? src[1] : src[3]; 368 dst[10] = mix(dst[10], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.250 : 0.000); 369 dst[11] = mix(dst[11], blendPix, (needBlend && doLineBlend) ? ((haveSteepLine) ? 0.750 : ((haveShallowLine) ? 0.250 : 0.000)) : 0.000); 370 dst[12] = mix(dst[12], blendPix, (needBlend && doLineBlend) ? ((!haveShallowLine && !haveSteepLine) ? 0.500 : 1.000) : 0.000); 371 dst[13] = mix(dst[13], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? 0.750 : ((haveSteepLine) ? 0.250 : 0.000)) : 0.000); 372 dst[14] = mix(dst[14], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.250 : 0.000); 373 dst[25] = mix(dst[25], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.250 : 0.000); 374 dst[26] = mix(dst[26], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.750 : 0.000); 375 dst[27] = mix(dst[27], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 1.000 : 0.000); 376 dst[28] = mix(dst[28], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.000 : ((haveShallowLine) ? 0.750 : 0.500)) : 0.05652034508) : 0.000); 377 dst[29] = mix(dst[29], blendPix, (needBlend) ? ((doLineBlend) ? 1.000 : 0.4236372243) : 0.000); 378 dst[30] = mix(dst[30], blendPix, (needBlend) ? ((doLineBlend) ? 1.000 : 0.9711013910) : 0.000); 379 dst[31] = mix(dst[31], blendPix, (needBlend) ? ((doLineBlend) ? 1.000 : 0.4236372243) : 0.000); 380 dst[32] = mix(dst[32], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.000 : ((haveSteepLine) ? 0.750 : 0.500)) : 0.05652034508) : 0.000); 381 dst[33] = mix(dst[33], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 1.000 : 0.000); 382 dst[34] = mix(dst[34], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.750 : 0.000); 383 dst[35] = mix(dst[35], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.250 : 0.000); 384 385 dist_01_04 = DistYCbCr(src[7], src[2]); 386 dist_03_08 = DistYCbCr(src[1], src[6]); 387 haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[2]) && (v[3] != v[2]); 388 haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[6]) && (v[5] != v[6]); 389 needBlend = (blendResult[1] != BLEND_NONE); 390 doLineBlend = ( blendResult[1] >= BLEND_DOMINANT || 391 !((blendResult[0] != BLEND_NONE && !IsPixEqual(src[0], src[2])) || 392 (blendResult[2] != BLEND_NONE && !IsPixEqual(src[0], src[6])) || 393 (IsPixEqual(src[2], src[1]) && IsPixEqual(src[1], src[8]) && IsPixEqual(src[8], src[7]) && IsPixEqual(src[7], src[6]) && !IsPixEqual(src[0], src[8])) ) ); 394 395 dist_01_04 = DistYCbCr(src[7], src[2]); 396 dist_03_08 = DistYCbCr(src[1], src[6]); 397 haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[2]) && (v[3] != v[2]); 398 haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[6]) && (v[5] != v[6]); 399 needBlend = (blendResult[1] != BLEND_NONE); 400 doLineBlend = ( blendResult[1] >= BLEND_DOMINANT || 401 !((blendResult[0] != BLEND_NONE && !IsPixEqual(src[0], src[2])) || 402 (blendResult[2] != BLEND_NONE && !IsPixEqual(src[0], src[6])) || 403 (IsPixEqual(src[2], src[1]) && IsPixEqual(src[1], src[8]) && IsPixEqual(src[8], src[7]) && IsPixEqual(src[7], src[6]) && !IsPixEqual(src[0], src[8])) ) ); 404 405 blendPix = ( DistYCbCr(src[0], src[7]) <= DistYCbCr(src[0], src[1]) ) ? src[7] : src[1]; 406 dst[ 7] = mix(dst[ 7], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.250 : 0.000); 407 dst[ 8] = mix(dst[ 8], blendPix, (needBlend && doLineBlend) ? ((haveSteepLine) ? 0.750 : ((haveShallowLine) ? 0.250 : 0.000)) : 0.000); 408 dst[ 9] = mix(dst[ 9], blendPix, (needBlend && doLineBlend) ? ((!haveShallowLine && !haveSteepLine) ? 0.500 : 1.000) : 0.000); 409 dst[10] = mix(dst[10], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? 0.750 : ((haveSteepLine) ? 0.250 : 0.000)) : 0.000); 410 dst[11] = mix(dst[11], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.250 : 0.000); 411 dst[20] = mix(dst[20], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.250 : 0.000); 412 dst[21] = mix(dst[21], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.750 : 0.000); 413 dst[22] = mix(dst[22], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 1.000 : 0.000); 414 dst[23] = mix(dst[23], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.000 : ((haveShallowLine) ? 0.750 : 0.500)) : 0.05652034508) : 0.000); 415 dst[24] = mix(dst[24], blendPix, (needBlend) ? ((doLineBlend) ? 1.000 : 0.4236372243) : 0.000); 416 dst[25] = mix(dst[25], blendPix, (needBlend) ? ((doLineBlend) ? 1.000 : 0.9711013910) : 0.000); 417 dst[26] = mix(dst[26], blendPix, (needBlend) ? ((doLineBlend) ? 1.000 : 0.4236372243) : 0.000); 418 dst[27] = mix(dst[27], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.000 : ((haveSteepLine) ? 0.750 : 0.500)) : 0.05652034508) : 0.000); 419 dst[28] = mix(dst[28], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 1.000 : 0.000); 420 dst[29] = mix(dst[29], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.750 : 0.000); 421 dst[30] = mix(dst[30], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.250 : 0.000); 422 423 dist_01_04 = DistYCbCr(src[5], src[8]); 424 dist_03_08 = DistYCbCr(src[7], src[4]); 425 haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[8]) && (v[1] != v[8]); 426 haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[4]) && (v[3] != v[4]); 427 needBlend = (blendResult[0] != BLEND_NONE); 428 doLineBlend = ( blendResult[0] >= BLEND_DOMINANT || 429 !((blendResult[3] != BLEND_NONE && !IsPixEqual(src[0], src[8])) || 430 (blendResult[1] != BLEND_NONE && !IsPixEqual(src[0], src[4])) || 431 (IsPixEqual(src[8], src[7]) && IsPixEqual(src[7], src[6]) && IsPixEqual(src[6], src[5]) && IsPixEqual(src[5], src[4]) && !IsPixEqual(src[0], src[6])) ) ); 432 433 blendPix = ( DistYCbCr(src[0], src[5]) <= DistYCbCr(src[0], src[7]) ) ? src[5] : src[7]; 434 dst[ 4] = mix(dst[ 4], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.250 : 0.000); 435 dst[ 5] = mix(dst[ 5], blendPix, (needBlend && doLineBlend) ? ((haveSteepLine) ? 0.750 : ((haveShallowLine) ? 0.250 : 0.000)) : 0.000); 436 dst[ 6] = mix(dst[ 6], blendPix, (needBlend && doLineBlend) ? ((!haveShallowLine && !haveSteepLine) ? 0.500 : 1.000) : 0.000); 437 dst[ 7] = mix(dst[ 7], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? 0.750 : ((haveSteepLine) ? 0.250 : 0.000)) : 0.000); 438 dst[ 8] = mix(dst[ 8], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.250 : 0.000); 439 dst[35] = mix(dst[35], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.250 : 0.000); 440 dst[16] = mix(dst[16], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.750 : 0.000); 441 dst[17] = mix(dst[17], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 1.000 : 0.000); 442 dst[18] = mix(dst[18], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.000 : ((haveShallowLine) ? 0.750 : 0.500)) : 0.05652034508) : 0.000); 443 dst[19] = mix(dst[19], blendPix, (needBlend) ? ((doLineBlend) ? 1.000 : 0.4236372243) : 0.000); 444 dst[20] = mix(dst[20], blendPix, (needBlend) ? ((doLineBlend) ? 1.000 : 0.9711013910) : 0.000); 445 dst[21] = mix(dst[21], blendPix, (needBlend) ? ((doLineBlend) ? 1.000 : 0.4236372243) : 0.000); 446 dst[22] = mix(dst[22], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.000 : ((haveSteepLine) ? 0.750 : 0.500)) : 0.05652034508) : 0.000); 447 dst[23] = mix(dst[23], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 1.000 : 0.000); 448 dst[24] = mix(dst[24], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.750 : 0.000); 449 dst[25] = mix(dst[25], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.250 : 0.000); 450 451 452 dist_01_04 = DistYCbCr(src[3], src[6]); 453 dist_03_08 = DistYCbCr(src[5], src[2]); 454 haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[6]) && (v[7] != v[6]); 455 haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[2]) && (v[1] != v[2]); 456 needBlend = (blendResult[3] != BLEND_NONE); 457 doLineBlend = ( blendResult[3] >= BLEND_DOMINANT || 458 !((blendResult[2] != BLEND_NONE && !IsPixEqual(src[0], src[6])) || 459 (blendResult[0] != BLEND_NONE && !IsPixEqual(src[0], src[2])) || 460 (IsPixEqual(src[6], src[5]) && IsPixEqual(src[5], src[4]) && IsPixEqual(src[4], src[3]) && IsPixEqual(src[3], src[2]) && !IsPixEqual(src[0], src[4])) ) ); 461 462 blendPix = ( DistYCbCr(src[0], src[3]) <= DistYCbCr(src[0], src[5]) ) ? src[3] : src[5]; 463 dst[13] = mix(dst[13], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.250 : 0.000); 464 dst[14] = mix(dst[14], blendPix, (needBlend && doLineBlend) ? ((haveSteepLine) ? 0.750 : ((haveShallowLine) ? 0.250 : 0.000)) : 0.000); 465 dst[15] = mix(dst[15], blendPix, (needBlend && doLineBlend) ? ((!haveShallowLine && !haveSteepLine) ? 0.500 : 1.000) : 0.000); 466 dst[ 4] = mix(dst[ 4], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? 0.750 : ((haveSteepLine) ? 0.250 : 0.000)) : 0.000); 467 dst[ 5] = mix(dst[ 5], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.250 : 0.000); 468 dst[30] = mix(dst[30], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.250 : 0.000); 469 dst[31] = mix(dst[31], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.750 : 0.000); 470 dst[32] = mix(dst[32], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 1.000 : 0.000); 471 dst[33] = mix(dst[33], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.000 : ((haveShallowLine) ? 0.750 : 0.500)) : 0.05652034508) : 0.000); 472 dst[34] = mix(dst[34], blendPix, (needBlend) ? ((doLineBlend) ? 1.000 : 0.4236372243) : 0.000); 473 dst[35] = mix(dst[35], blendPix, (needBlend) ? ((doLineBlend) ? 1.000 : 0.9711013910) : 0.000); 474 dst[16] = mix(dst[16], blendPix, (needBlend) ? ((doLineBlend) ? 1.000 : 0.4236372243) : 0.000); 475 dst[17] = mix(dst[17], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.000 : ((haveSteepLine) ? 0.750 : 0.500)) : 0.05652034508) : 0.000); 476 dst[18] = mix(dst[18], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 1.000 : 0.000); 477 dst[19] = mix(dst[19], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.750 : 0.000); 478 dst[20] = mix(dst[20], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.250 : 0.000); 479 480 } 481 482 vec3 res = mix( mix( mix( mix( mix( mix(dst[20], dst[21], step(one_sixth, f.x) ), dst[22], step(two_sixth, f.x) ), mix( mix(dst[23], dst[24], step(four_sixth, f.x) ), dst[25], step(five_sixth, f.x) ), step(0.50, f.x) ), 483 mix( mix( mix(dst[19], dst[ 6], step(one_sixth, f.x) ), dst[ 7], step(two_sixth, f.x) ), mix( mix(dst[ 8], dst[ 9], step(four_sixth, f.x) ), dst[26], step(five_sixth, f.x) ), step(0.50, f.x) ), step(one_sixth, f.y) ), 484 mix( mix( mix(dst[18], dst[ 5], step(one_sixth, f.x) ), dst[ 0], step(two_sixth, f.x) ), mix( mix(dst[ 1], dst[10], step(four_sixth, f.x) ), dst[27], step(five_sixth, f.x) ), step(0.50, f.x) ), step(two_sixth, f.y) ), 485 mix( mix( mix( mix( mix(dst[17], dst[ 4], step(one_sixth, f.x) ), dst[ 3], step(two_sixth, f.x) ), mix( mix(dst[ 2], dst[11], step(four_sixth, f.x) ), dst[28], step(five_sixth, f.x) ), step(0.50, f.x) ), 486 mix( mix( mix(dst[16], dst[15], step(one_sixth, f.x) ), dst[14], step(two_sixth, f.x) ), mix( mix(dst[13], dst[12], step(four_sixth, f.x) ), dst[29], step(five_sixth, f.x) ), step(0.50, f.x) ), step(four_sixth, f.y) ), 487 mix( mix( mix(dst[35], dst[34], step(one_sixth, f.x) ), dst[33], step(two_sixth, f.x) ), mix( mix(dst[32], dst[31], step(four_sixth, f.x) ), dst[30], step(five_sixth, f.x) ), step(0.50, f.x) ), step(five_sixth, f.y) ), 488 step(0.50, f.y) ); 489 490 FragColor = vec4(res, 1.0); 491} 492#endif 493