From 396cd2450bd3026144d83d3bf1c60e5abca615aa Mon Sep 17 00:00:00 2001 From: crashGG <80488411+crashGG@users.noreply.github.com> Date: Tue, 14 Apr 2026 18:54:34 +0300 Subject: [PATCH] Update tex_mmpx_adv.csh --- assets/shaders/tex_mmpx_adv.csh | 1743 +++++++++++++------------------ 1 file changed, 749 insertions(+), 994 deletions(-) diff --git a/assets/shaders/tex_mmpx_adv.csh b/assets/shaders/tex_mmpx_adv.csh index 4a7aa8270a..45b103c72f 100644 --- a/assets/shaders/tex_mmpx_adv.csh +++ b/assets/shaders/tex_mmpx_adv.csh @@ -3,7 +3,7 @@ Provided under the Open Source MIT license https://opensource.org/licenses/MIT by Morgan McGuire and Mara Gagiu. - 2025 Enhanced by CrashGG. + 2025-2026 Enhanced by CrashGG. */ // Performs 2x upscaling. @@ -15,1298 +15,1053 @@ in ppsspp ,readColorf(p) eq unpackUnorm4x8(readColoru(p)),It is not actually read directly. */ -uint src(int x, int y) { +precision mediump float; - // Old clamp method: always return center pixel when coordinates are out of bounds - //return readColoru(uvec2(clamp(x, 0, params.width - 1), clamp(y, 0, params.height - 1))); +uint srcu(int x, int y) { - // Better out-of-bounds check: test if coordinates are valid first. Return transparent if out of bounds. + // First perform out-of-bounds check to determine if coordinates are within valid range. Return transparent color if out of bounds. return (x >= 0 && x < params.width && y >= 0 && y < params.height) ? readColoru(uvec2(x, y)) : 0u; } +#define src(c,d) unpackUnorm4x8(srcu(c,d)) -// RGB perceptual weight + alpha tiered segmentation +//RGB visual weight + alpha segmentation float luma(vec4 col) { - // Use CRT-era BT.601 standard. Result divided by 10, range [0.0 - 0.1] - float rgbsum =dot(col.rgb, vec3(0.0299, 0.0587, 0.0114)); + //Use the CRT-era BT.601 standard. Clamp the result to [0.0 - 0.999] + float rgbsum =min(dot(col.rgb, vec3(0.299, 0.587, 0.114)), 0.999); - // Remove alpha weighting by taking fractional part and *10 later - float alphafactor = - (col.a > 0.854102) ? 1.0 : // Upper segment of two short golden ratio splits - (col.a > 0.618034) ? 2.0 : // One golden ratio split - (col.a > 0.381966) ? 3.0 : // One short golden ratio split - (col.a > 0.145898) ? 4.0 : // Two short golden ratio splits - (col.a > 0.002) ? 5.0 : 8.0; // Fully transparent + // Alpha weighting can be removed for subsequent decimal extraction + float alphafactor = 10.0 + - step(0.002, col.a) * 2.0 // Fully transparent + - step(0.145898, col.a) * 2.0 // 2nd short golden ratio division + - step(0.381966, col.a) * 2.0 // 1st short golden ratio division + - step(0.618034, col.a) * 2.0 // 1st golden ratio division + - step(0.854102, col.a) * 2.0; // Upper part of 2nd short golden ratio division return rgbsum + alphafactor; } -/* Constant definitions: -0.145898 : Two short golden ratio splits of 1.0 -0.0638587 : Squared Euclidean RGB distance after two short golden ratio splits -0.024391856 : Squared Euclidean RGB distance after two short + one golden ratio split -0.00931686 : Squared Euclidean RGB distance after three short golden ratio splits -0.001359312 : Squared Euclidean RGB distance after four short golden ratio splits -0.4377 : Squared Euclidean RGB distance after one short golden ratio split -0.75 : Squared half Euclidean RGB distance +/* Constant Definitions: +0.145898 : Two short golden ratio divisions of 1.0 +0.0638587 : Squared value after two short golden ratio divisions of RGB Euclidean distance +0.024391856 : Squared value after two short golden ratio divisions + one golden ratio division of RGB Euclidean distance +0.00931686 : Squared value after three short golden ratio divisions of RGB Euclidean distance +0.001359312 : Squared value after four short golden ratio divisions of RGB Euclidean distance +0.4377 : Squared value after one short golden ratio division of RGB Euclidean distance +0.75 : Squared value of half the RGB Euclidean distance */ -// Pixel similarity check - Level 1 -// pin zz -bool sim1(vec4 col1, vec4 col2) { - vec4 diff = col1 - col2; - vec4 absdiff = abs(diff); +bool simb(vec4 col1, vec4 col2) { - // 1. Fast component difference check - if ( absdiff.r > 0.1 || absdiff.g > 0.1 || absdiff.b > 0.1 || absdiff.a > 0.145898 ) return false; + highp vec4 diff = col1 - col2; - // 2. Fast squared distance check - float dot_diff = dot(diff.rgb, diff.rgb); - if (dot_diff < 0.001359312) return true; + float maxdiff = max(diff.r, max(diff.g, diff.b)); + float mindiff = min(diff.r, min(diff.g, diff.b)); - // 3. Gradient pixel check - float min_diff = min(diff.r, min(diff.g, diff.b)); - float max_diff = max(diff.r, max(diff.g, diff.b)); - if ( max_diff-min_diff>0.096 ) return false; // Reject if difference exceeds int24 - if ( max_diff-min_diff<0.024 && dot_diff<0.024391856) return true; // Treat as gradient if difference <= int6, wider threshold + // Luminance base weight: both colors must be > 0.078 (0.234÷3) + float weight = step(0.234, min(col1.r+col1.g+col1.b, col2.r+col2.g+col2.b)); + // Transparency base weight: both colors must be fully opaque + float weight2 = step(0.998, min(col1.a, col2.a)); - // 4. Grayscale pixel check - float sum1 = dot(col1.rgb, vec3(1.0)); // Sum RGB channels - float sum2 = dot(col2.rgb, vec3(1.0)); - float avg1 = sum1 * 0.3333333; - float avg2 = sum2 * 0.3333333; + // Find the most opposite channel: if one positive and one negative, take the smallest absolute value; 0 if same sign + // Use max(0.0, ...) to filter same-sign cases + // Skip team_rebel if either pixel has insufficient brightness (<0.078) or is not fully opaque + float team_rebel = min(max(0.0, maxdiff), max(0.0, -mindiff)) * weight * weight2; + float finaldist = (maxdiff - mindiff) + team_rebel; - vec3 graydiff1 = col1.rgb - vec3(avg1); - vec3 graydiff2 = col2.rgb - vec3(avg2); - float dotgray1 = dot(graydiff1,graydiff1); - float dotgray2 = dot(graydiff2,graydiff2); - // 0.002: Allow single-channel diff up to int13 when avg=20. 0.0004: Allow single-channel diff up to int6, dual-channel int3+4 - float tolerance1 = avg1<0.08 ? 0.002 : 0.0004; - float tolerance2 = avg2<0.08 ? 0.002 : 0.0004; - // 0.078: Max green channel = 19, perceptible limit to human eye - bool Col1isGray = sum1<0.078||dotgray10.381966) return false; - - return rgbDist(colC1.rgb, colC2.rgb) < 0.024391856; -} - -bool sim2(vec4 col1, vec4 col2) { - // Ignore RGB if both pixels are near-transparent if ( col1.a < 0.381966 && col2.a < 0.381966 ) return true; - // Alpha difference must not exceed 0.382 - if ( abs(col1.a-col2.a)>0.381966) return false; - return rgbDist(col1.rgb, col2.rgb) < 0.024391856; -} -bool sim3(vec4 col1, vec4 col2) { - // Ignore RGB if both pixels are near-transparent - if ( col1.a < 0.145898 && col2.a < 0.145898 ) return true; - // Alpha difference must not exceed 0.382 - if ( abs(col1.a-col2.a)>0.381966) return false; - return rgbDist(col1.rgb, col2.rgb) < 0.0638587; + return simb(col1,col2); } bool mixcheck(vec4 col1, vec4 col2) { - // Transparent pixels filtered out externally - vec4 diff = col1 - col2; - // Reject mixing if alpha difference exceeds half range - if ( abs(diff.a) > 0.5 ) return false; + highp vec4 diff = col1 - col2; - // Gradient pixel check - float min_diff = min(diff.r, min(diff.g, diff.b)); - float max_diff = max(diff.r, max(diff.g, diff.b)); - if ( max_diff-min_diff>0.618034 ) return false; + // Three-channel color difference (max_diff - min_diff) + float delta_range = max(diff.r, max(diff.g, diff.b)) - min(diff.r, min(diff.g, diff.b)); - float dot_diff = dot(diff.rgb, diff.rgb); - if( max_diff-min_diff<0.024 && dot_diff<0.75) return true; // 0.020 <= int5, 0.024 <= int6 + highp float dot_diff = dot(diff.rgb, diff.rgb); - // Accumulate positive/negative values using max/min - float team_pos = abs(dot(max(diff.rgb, 0.0), vec3(1.0))); - float team_neg = abs(dot(min(diff.rgb, 0.0), vec3(1.0))); - // Add opposing channel to squared distance before final check - float team_rebel = min(team_pos, team_neg); - // Empirically requires at least 3x opposing channel value (1x neutralizes, 2x creates upward trend) - return dot_diff + team_rebel*team_rebel*3.0 < 0.4377; + // Equivalent to (delta_range ÷ 0.618 )² + highp float factor = (delta_range * delta_range) * 2.618034; + + return abs(diff.a) < 0.5 && dot_diff < mix(0.75, 0.0, factor); } -// RGB must match, minor alpha differences allowed -bool eq(uint C1, uint C2){ - if (C1 == C2) return true; - - uint rgbC1 = C1 & 0x00FFFFFFu; - uint rgbC2 = C2 & 0x00FFFFFFu; - - if (rgbC1 != rgbC2) return false; - - uint alphaC1 = C1 >> 24; - uint alphaC2 = C2 >> 24; - - // Note: uint cannot use abs(alphaC1-alphaC2)! - uint alphaDiff = (alphaC1 > alphaC2) ? (alphaC1 - alphaC2) : (alphaC2 - alphaC1); - - return alphaDiff < 38u; // Two short golden ratio splits of 255u - +bool fastcheck(vec4 col1, vec4 col2) { + vec4 diff = col1 - col2; + return dot(diff, diff) < 0.75; } -#define noteq(a,b) (a!=b) +#define eq(a,b) all(lessThan(abs(a-b), vec4(0.01, 0.01, 0.01, 0.145898))) -bool vec_noteq(vec4 col1, vec4 col2) { - vec4 diff = abs(col1 - col2); - // Allow total RGB diff <= int2, alpha diff <= int5 - return dot(diff.rgb, vec3(1.0)) > 0.008 || diff.a > 0.021286; -} +#define neq(a,b) !eq(a,b) -bool all_eq2(uint B, uint A0, uint A1) { - return (eq(B,A0) && eq(B,A1)); -} +#define all_eq2(a, b1, b2) \ + ( eq(a,b1) && eq(a,b2)) -bool any_eq2(uint B, uint A0, uint A1) { - return (eq(B,A0) || eq(B,A1)); -} +#define all_eq3(a, b1, b2, b3) \ + ( eq(a,b1) && eq(a,b2) && eq(a,b3)) -bool any_eq3(uint B, uint A0, uint A1, uint A2) { - return (eq(B,A0) || eq(B,A1) || eq(B,A2)); -} +#define all_eq4(a, b1, b2, b3, b4) \ + ( eq(a,b1) && eq(a,b2) && eq(a,b3) && eq(a,b4)) + +#define any_eq2(a, b1, b2) (eq(a,b1)||eq(a,b2)) +#define any_eq3(a, b1, b2, b3) (eq(a,b1)||eq(a,b2)||eq(a,b3)) +// Better than a!=b1 && a!=b2 +#define none_eq2(a, b1, b2) !any_eq2(a, b1, b2) + + +// Total int2 difference allowed for three channels +//#define vec_neq(a,b) (dot(abs(a-b), vec4(1.0)) > 0.01) +// Int2 difference allowed per three-channel +//#define vec_eq(a,b) all(lessThan(abs(a-b), vec4(0.01))) +#define vec_neq(a, b) !eq(a,b) -bool none_eq2(uint B, uint A0, uint A1) { - return (noteq(B,A0) && noteq(B,A1)); -} // Pre-define -//#define testcolor vec4(1.0, 0.0, 1.0, 1.0) // Magenta -//#define testcolor2 vec4(0.0, 1.0, 1.0, 1.0) // Cyan -//#define testcolor3 vec4(1.0, 1.0, 0.0, 1.0) // Yellow -//#define testcolor4 vec4(1.0, 1.0, 1.0, 1.0) // White - -#define slopeBAD vec4(2.0) -#define theEXIT vec4(4.0) -#define slopOFF vec4(8.0) -#define Mix382 mix(colX,colE,0.381966) -#define Mix618 mix(colX,colE,0.618034) -#define Mix854 mix(colX,colE,0.8541) +//const vec4 testcolor = vec4(1.0, 0.0, 1.0, 1.0); // Magenta +//const vec4 testcolor2 = vec4(0.0, 1.0, 1.0, 1.0); // Cyan +//const vec4 testcolor3 = vec4(1.0, 1.0, 0.0, 1.0); // Yellow +//const vec4 testcolor4 = vec4(1.0, 1.0, 1.0, 1.0); // White +const vec4 slopOFF = vec4(2.0); +const vec4 slopeBAD = vec4(4.0); +const vec4 theEXIT = vec4(8.0); +#define Mix382 mix(vX, vE, 0.381966) +#define Mix618 mix(vX, vE, 0.618034) +#define Mix854 mix(vX, vE, 0.8541) #define Mix382off Mix382+slopOFF #define Mix618off Mix618+slopOFF #define Mix854off Mix854+slopOFF -#define Xoff colX+slopOFF -#define checkblack(col) ((col).g < 0.078 && (col).r < 0.1 && (col).b < 0.1) -#define diffEB abs(El-Bl) -#define diffED abs(El-Dl) -#define writeJKLM writeColorf(destXY,J);writeColorf(destXY+ivec2(1,0),K);writeColorf(destXY+ivec2(0,1),L);writeColorf(destXY+ivec2(1,1),M) +#define Xoff vX+slopOFF +//#define checkblack(col) ((col).g < 0.078 && (col).r < 0.1 && (col).b < 0.1) +#define checkblack(col) all(lessThan((col).rgb, vec3(0.1, 0.078, 0.1))) + //pin zz -// Concave + Cross pattern - Weak blending (weak/none) -vec4 admixC(vec4 colX, vec4 colE) { - // Transparent pixels filtered out in main logic +// Concave + Cross pattern - Weak blending (weak blend/none) +vec4 admixC(vec4 vX, vec4 vE) { - bool mixok = mixcheck(colX, colE); + bool mixok = mixcheck(vX, vE); - return mixok ? Mix618 : colE; + return mixok ? Mix618 : vE; } -// K-pattern - Forced weak blending (weaker) -vec4 admixK(vec4 colX, vec4 colE) { - // Transparent pixels filtered out in main logic +// K-pattern - Forced weak blending (weaker blend) +vec4 admixK(vec4 vX, vec4 vE) { - bool mixok = mixcheck(colX, colE); + bool mixok = mixcheck(vX, vE); return mixok ? Mix618 : Mix854; } -// L-pattern - 2:1 slope - Main corner extension -// Practical rule: This requires 4 pixels on strict slope to be identical, otherwise severe aliasing occurs! -vec4 admixL(vec4 colX, vec4 colE, vec4 colS) { +// L-pattern - 2:1 slope - Extension of main corner +// Practice: This rule requires 4 pixels on the strict slope to be identical. Otherwise, various glitches will appear! +vec4 admixL(vec4 vX, vec4 vE, vec4 vS) { - // Original eq(X,E) check caught many duplicate pixels; now filtered by slopeok in main logic + // The original eq(X,E) check would catch many duplicate pixels, now the main thread has been filtered by slopeok. - // Copy directly if target X differs from sample S (already blended once), no re-blend - if (vec_noteq(colX, colS)) return colX; + // If target X is different from reference S(sample), it means blending has been done once; copy directly without re-blending + if (vec_neq(vX, vS)) return vX; - bool mixok = mixcheck(colX, colE); + bool mixok = mixcheck(vX, vE); - return mixok ? Mix382 : colX; + return mixok ? Mix382 : vX; } +#define vE E +#define vB B +#define vD D +#define vF F +#define vH H +#define vA A +#define vC C +#define vG G +#define vI I + /************************************************************************************************************************************** * main slope + X cross-processing mechanism * ******************************************************************************************************************************** zz */ -vec4 admixX(uint A, uint B, uint C, uint D, uint E, uint F, uint G, uint H, uint I, - uint P, uint PA, uint PC, uint Q, uint QA, uint QG, uint R, uint RC, uint RI, uint S, uint SG, uint SI, uint AA, uint CC, uint GG, - float El, float Bl, float Dl, float Fl, float Hl, - vec4 colE, vec4 colB, vec4 colD, vec4 colC, vec4 colG, - bool eq_B_D, bool eq_F_H, bool eq_E_A, bool eq_E_C, bool eq_E_G, bool eq_E_I, bool eq_E_F, bool eq_E_H) { +vec4 admixX( vec4 A, vec4 B, vec4 C, vec4 D, vec4 E, vec4 F, vec4 G, vec4 H, vec4 I + , vec4 P, vec4 PA, vec4 PC, vec4 Q, vec4 QA, vec4 QG, vec4 R, vec4 RC, vec4 RI, vec4 S, vec4 SG, vec4 SI, vec4 AA, vec4 CC, vec4 GG + , float El, float Bl, float Dl, float Fl, float Hl + //, vec4 vE, vec4 vB, vec4 vD, vec4 vC, vec4 vG + ) { + bool eq_B_C = eq(B,C); + bool eq_D_G = eq(D,G); - bool eq_B_C = eq(B, C); - bool eq_D_G = eq(D, G); - - // Exit if enclosed by dual straight walls + // Exit if sandwiched by double-sided straight walls if (eq_B_C && eq_D_G) return slopeBAD; - // Pre-declare variables - bool eq_A_B; bool eq_A_D; bool eq_A_P; bool eq_A_Q; + + //Pre-declare bool eq_B_P; bool eq_B_PA; bool eq_B_PC; bool eq_D_Q; bool eq_D_QA; bool eq_D_QG; - bool B_slope; bool B_tower; bool B_wall; - bool D_slope; bool D_tower; bool D_wall; - vec4 colX; bool Xisblack; + bool eq_E_F; bool eq_E_H; bool eq_A_AA; + + vec4 vX; bool mixok; - bool comboA3; bool En3; - - #define En4square En3 && eq_E_I - // E is near-transparent (not fully) - essentially an edge pixel - bool EalphaL = colE.a >0.002 && colE.a <0.381966; - // Remove alpha channel weighting - Bl = fract(Bl) *10.0; - Dl = fract(Dl) *10.0; - El = fract(El) *10.0; - Fl = fract(Fl) *10.0; - Hl = fract(Hl) *10.0; + bool eq_E_C = eq(E,C); + bool eq_E_G = eq(E,G); + bool eq_A_P = eq(A,P); + bool eq_A_Q = eq(A,Q); + bool comboE3 = eq_E_C && eq_E_G; + bool comboA3 = eq_A_P && eq_A_Q; /*========================================= B != D ==================================== zz */ -if (!eq_B_D){ +if (neq(B,D)){ - // Exit if E == A (violates expected logic) - if (eq_E_A) return slopeBAD; + // E-A equality violates preset logic, exit + if (eq(E,A)) return slopeBAD; + // B-D bilateral disconnection (stricter than three-sided isolation) + // if ( !eq(B,C) && !eq(B,P) && !eq(B,PC) || !eq(D,G) && !eq(D,Q) && !eq(D,QG) ) return slopeBAD; + // Non-slope (strictest, unnecessary) + //if (B==PC||D!=QG) return slopeBAD; - // Exit if B and D differ more than either differs from center E + // B and D are different, with large difference greater than either side to center E; exit float diffBD = abs(Bl-Dl); - if (diffBD > diffEB || diffBD > diffED) return slopeBAD; - - // Prevent single-pixel font edges from being crushed by black background (luminance diff > 0.5) - // Note: If B != D, use both black checks, not average - Xisblack = checkblack(colB) && checkblack(colD); - if ( Xisblack && El >0.5 && (Fl<0.078 || Hl<0.078) ) return theEXIT; - - // Exclusion rule before original logic (triangular vertices cannot protrude) - eq_A_B = eq(A,B); - if ( !Xisblack && eq_A_B && eq_D_G && eq(B,P) ) return slopeBAD; - - eq_A_D = eq(A,D); - if ( !Xisblack && eq_A_D && eq_B_C && eq(D,Q) ) return slopeBAD; - - // B and D are isolated? Not applicable here (fixes some artifacts but loses shapes, e.g. Double Dragon attract mode character art) - - // X is B/D 50/50 blend - colX = mix(colB, colD, 0.5); - colX.a = min(colB.a, colD.a); - - mixok = E!=0u && mixcheck(colX,colE); - - eq_A_P = eq(A,P); - eq_A_Q = eq(A,Q); - comboA3 = eq_A_P && eq_A_Q; - // High priority: 3-in-a-row on A side - if (comboA3) return mixok ? Mix382off : Xoff; - - // Original official rule - if ( eq_E_C || eq_E_G ) return mixok ? Mix382off : Xoff; - - // Original rule enhancement 1 - Catches trends well, enhancement 2 disabled (wall bypass issue) - if ( !eq_D_G&&eq(E,QG)&&sim2(colE,colG) || !eq_B_C&&eq(E,PC)&&sim2(colE,colC) ) return mixok ? Mix382off : Xoff; + if (diffBD > El-Bl || diffBD > El-Dl) return slopeBAD; - // Exclude 3-pixel single-side wall cases - if (!Xisblack){ - if ( eq_A_B&&eq_B_C || eq_A_D&&eq_D_G ) return slopeBAD; - } + // X is the blend of B and D + vX = mix(vB, vD, 0.5); + vX.a = min(vB.a, vD.a); - if (EalphaL) return mixok ? Mix382off : Xoff; + mixok = vE.a>0.002 && mixcheck(vX,vE); - // F-H inline trend (includes En3), blocked by 3-pixel wall rule so placed after - if ( eq_F_H ) return mixok ? Mix382off : Xoff; + eq_B_PC = eq(B,PC); + eq_D_QG = eq(D,QG); + + // Strong trend collection + if (none_eq2(A,B,D)){ + if (comboA3) return mixok ? Mix382off : Xoff; + if ( eq_A_P && eq_B_PC && !eq_B_C ) return mixok ? Mix382off : Xoff; + if ( eq_A_Q && eq_D_QG && !eq_D_G ) return mixok ? Mix382off : Xoff; + + // Double slope sandwiching BD, note direction matching + if ( eq_A_P && eq_E_G ) return mixok ? Mix382off : Xoff; + if ( eq_A_Q && eq_E_C ) return mixok ? Mix382off : Xoff; + + // Hollow L - inner curve + if ( eq_E_C && eq_D_G ) return mixok ? Mix382off : Xoff; + if ( eq_E_G && eq_B_C ) return mixok ? Mix382off : Xoff; + +} + // E-side three-pixel alignment + if ( comboE3 ) return mixok ? Mix382off : Xoff; + + // Original rule with added slope condition + if ( eq_E_C && eq_B_PC && neq(B,P)) return mixok ? Mix382off : Xoff; + if ( eq_E_G && eq_D_QG && neq(D,Q)) return mixok ? Mix382off : Xoff; + + eq_E_F = eq(E,F); + + // F - H + if (eq(F,H)) { + + // Double slope (exclude single-pixel surrounded by C, BD different colors with weak connection) + if ( eq_E_C && !eq_D_G && (!eq_E_F||neq(E,P)) ) return mixok ? Mix382off : Xoff; + if ( eq_E_G && !eq_B_C && (!eq_E_F||neq(E,Q)) ) return mixok ? Mix382off : Xoff; + + // F+ H+ extension + if ( !eq_E_F && eq_B_PC && eq(F,RC) ) return mixok ? Mix382off : Xoff; + if ( !eq_E_F && eq_D_QG && eq(H,SG) ) return mixok ? Mix382off : Xoff; + } - // Abort remaining 2-pixel walls and random single pixels return slopeBAD; } // B != D -/******* B == D prepare *******/ + + /********* B == D *********/ + + //Remove alpha channel weighting + Bl = fract(Bl); + Dl = fract(Dl); + El = fract(El); + Fl = fract(Fl); + Hl = fract(Hl); - // Prevent font edges from being crushed on 3 sides by black background - Xisblack = checkblack(colB); + // Avoid font edges being squeezed by black background on three sides + bool Xisblack = checkblack(vB); if ( Xisblack && El >0.5 && (Fl<0.078 || Hl<0.078) ) return theEXIT; - colX = colB; - colX.a = min(colB.a , colD.a); + vX = vB; + vX.a = min(vB.a, vD.a); - float distEC = float(!eq_E_C); - float distEG = float(!eq_E_G); - - if (!eq_E_C) { - if ( colE.a<0.381966 && colC.a<0.381966 ) { // Ignore RGB if both near-transparent - distEC = 0.0; - } else if (abs(colE.a-colC.a)<0.381966) distEC = rgbDist(colE.rgb, colC.rgb); - } - if (!eq_E_G) { - if ( colE.a<0.381966 && colG.a<0.381966 ) { // Ignore RGB if both near-transparent - distEC = 0.0; - } else if (abs(colE.a-colG.a)<0.381966) distEG = rgbDist(colE.rgb, colG.rgb); - } - - bool sim_EC = distEC < 0.024391856; - bool sim_EG = distEG < 0.024391856; - - bool comboE3 = eq_E_C && eq_E_G; - bool ThickBorder; - - -/*=============================================== - Original main rules sim2 enhanced - ========================================== zz */ -if ( (sim_EC || sim_EG) && !eq_E_A ){ - -/* Logic: - 1. Skip blending for continuous border shapes - 2. Special handling for long slopes - 3. Original rules - 4. Handle En4/En3/F-H inline patterns, remaining lines and single pixels - 5. Remove L-notch inner lines and outer lines - 6. Default fallback return -*/ - - eq_A_B = eq(B,A); - eq_B_P = eq(B,P); - eq_B_PC = eq(B,PC); - eq_B_PA = eq(B,PA); - eq_D_Q = eq(D,Q); - eq_D_QG = eq(D,QG); - eq_D_QA = eq(D,QA); - B_slope = eq_B_PC && !eq_B_P && !eq_B_C; - B_tower = eq_B_P && !eq_B_PC && !eq_B_C && !eq_B_PA; - D_slope = eq_D_QG && !eq_D_Q && !eq_D_G; - D_tower = eq_D_Q && !eq_D_QG && !eq_D_G && !eq_D_QA; - - - // Strong shape: B/D both extend patterns - if ( (B_slope||B_tower) && (D_slope||D_tower) && !eq_A_B) return Xoff; - - mixok = E!=0u && mixcheck(colX,colE); - - eq_A_P = eq(A, P); - eq_A_Q = eq(A, Q); - comboA3 = eq_A_P && eq_A_Q; - - ThickBorder = eq_A_B && (eq_A_P||eq_A_Q|| eq(A,AA)&&(eq_B_PA||eq_D_QA)); - - if (ThickBorder && !Xisblack) mixok=false; - - // 3-in-a-row on A side - if (comboA3) { - if (!eq_A_B) return Xoff; // Hollow: return strong shape - else mixok=false; // Solid: disable blending - } - - // 3-in-a-row on E side - if (comboE3) return mixok ? Mix382off : Xoff; - - - B_wall = eq_B_C && !eq_B_PC && !eq_B_P; - D_wall = eq_D_G && !eq_D_QG && !eq_D_Q; - - // Clear long slope (non-thick border edge - strong trend!) - // Special condition for long slopes - if ( B_wall && D_tower ) { - if (eq_E_G || sim_EG&&eq(E,QG) ) { // Original + enhanced rule - if (eq_A_B) return mixok ? Mix382 : colX; // Has thickness - return colX; // Hollow - } - if (eq_A_B) return slopeBAD; - // 2-pixel with long slope continuation - if (eq_E_F ) return colX; - // 1-pixel without long slope - return Xoff; - } - - if ( B_tower && D_wall ) { - if (eq_E_C || sim_EC&&eq(E,PC) ) { // Original + enhanced rule - if (eq_A_B) return mixok ? Mix382 : colX; // Has thickness - return colX; // Hollow - } - if (eq_A_B) return slopeBAD; - // 2-pixel with long slope continuation - if (eq_E_H ) return colX; - // 1-pixel without long slope - return Xoff; - } - - - // Official original rules (placed after special shapes - they specify no blending!) - // Fixes for original rules - if (eq_E_C ) { - if (eq_A_B && eq_B_PA && !eq_B_PC && eq_E_F && eq(E,P)) return theEXIT; - return mixok ? Mix382 : colX; - } - - if (eq_E_G) { - if (eq_A_B && eq_D_QA && !eq_D_QG && eq_E_H && eq(E,Q)) return theEXIT; - return mixok ? Mix382 : colX; - } - - // Original rule enhancement 1 - if (sim_EG&&!eq_D_G&&eq(E,QG) || sim_EC&&!eq_B_C&&eq(E,PC)) return mixok ? Mix382off : Xoff; - - // Original rule enhancement 2 - if (sim_EC && sim_EG) return mixok ? Mix382off : Xoff; - - - // F-H inline trend (skip En4/En3) - if ( eq_F_H ) return mixok ? Mix382off : Xoff; - - // Cleanup final long slopes (non-clear shapes) - // Practical: This section cleans slopes differently than F-H - default neutral unless cube - if (eq_B_C && eq_D_Q) { - // Double cube: exit - if (eq_B_P && eq_B_PC && eq_A_B && eq_D_QA && !eq_D_QG && eq_E_F && eq(H,I) ) return theEXIT; - - return mixok ? Mix382off : Xoff; - } - - if ( eq_D_G && eq_B_P) { - // Double cube: exit - if (eq_D_Q && eq_D_QG && eq_A_B && eq_B_PA && !eq_B_PC && eq_E_H && eq(F,I) ) return theEXIT; - - return mixok ? Mix382off : Xoff; - } - - - // Exit for clear L-notch inner parallel line - if (eq_A_B && !ThickBorder && !eq_E_I ) { - if (B_wall && eq_E_F) return theEXIT; - if (D_wall && eq_E_H) return theEXIT; - } - - // Early return if colors are similar - if (mixok) return Mix382off; - if (EalphaL) return mixok ? Mix382off : Xoff; - - // Exit for hollow L-corner outer line (fixes font edge artifacts) - if ( !eq_A_B && (eq_E_F||eq_E_H) && !eq_E_I) { - if (B_tower && !eq_D_Q && !eq_D_QG) return theEXIT; - if (D_tower && !eq_B_P && !eq_B_PC) return theEXIT; - } - - // Fallback handler - return mixok ? Mix382off : Xoff; - -} // sim2 base + mixok = vE.a>0.002 && mixcheck(vX,vE); + bool B_slope; bool B_tower; bool B_wall; + bool D_slope; bool D_tower; bool D_wall; + bool En3; + #define En4square En3&&eq(E,I) /*=================================================== E - A Cross ============================================== zz */ -if (eq_E_A) { +if (eq(E,A)) { - // Cross checks need "region" and "trend" concepts - tighter conditions per region + // Special pattern: Dithering + // Target: Forced blending - // B/D isolated exit? Not needed here!!! + eq_E_F = eq(E,F); + eq_E_H = eq(E,H); - - En3 = eq_E_F&&eq_E_H; - - // Special shape: Square (En4square) - if ( En4square ) { - if( noteq(G,H) && noteq(C,F) // Independent clear 4-pixel square / 6-pixel rectangle (both sides valid) - && (eq(H,S) == eq(I,SI) && eq(F,R) == eq(I,RI)) ) return theEXIT; - //else return mixok ? mix(X,E,0.381966) : X; Do NOT return directly - enter checkerboard rule (adjacent B/D may form bubbles) - } - - // Special shape: Dithering pattern - // Practical 1: Use !eq_E_F / !eq_E_H (not !sim) to preserve shapes - // Practical 2: Force blending to preserve shapes (Karnov's Revenge, Muscle Bomber 2) - - bool Eisblack = checkblack(colE); - mixok = E!=0u && mixcheck(colX,colE); + bool Eisblack = checkblack(vE); // 1. Dithering center - if ( comboE3 && eq_E_I && !eq_E_F && !eq_E_H ) { + if ( comboE3 && !eq_E_F && !eq_E_H && eq(E,I) ) { - // Exit if center E is black (KOF '96 power gauge, Punisher belt) - avoid high-contrast blending + // Exit if center E is black (KOF 96 power gauge, The Punisher belt) to avoid excessive contrast blending if (Eisblack) return theEXIT; - // Practical 1: Skip black B checks (normal logic entry) - // Practical 2: No need for eq_F_H check (>95% chance) + gradient blending inside gauge, 0.5 fallback + // Practice 1: Do not catch black B points (normal logic entry) + // Practice 2: No need to check eq(F,H) separately (>95% probability) + layered gradient in health gauge, 0.5 fallback blend return mixok ? Mix382off : Mix618off; } - eq_B_PA = eq(B,PA); - eq_A_P = eq(A,P); - eq_A_Q = eq(A,Q); - comboA3 = eq_A_P && eq_A_Q; + + eq_A_AA = eq(A,AA); // 2. Dithering edge - if ( comboA3 && eq(A,AA) && noteq(A,PA) && noteq(A,QA) ) { + if ( comboA3 && eq_A_AA && none_eq2(A,PA,QA) ) { if (Eisblack) return theEXIT; - // Strong blend for gradient edges - if ( !eq_B_PA && eq(PA,QA) ) return mixok ? Mix382off : Mix618off; - // Remainder: perfect cross = dithering edge, weak blend - // Default weak blend - no explicit gauge border handling needed + // Layered gradient edge, use strong blending + if ( neq(B,PA) && eq(PA,QA) ) return mixok ? Mix382off : Mix618off; + // Remaining perfect cross, must be dithering edge, use weak blending + // Fallback weak blending. No need to specify health gauge border separately. return mixok ? Mix618off : Mix854off; } - // Early return X if center fully transparent - if (E==0u) return colX; + // Return X early if center pixel is fully transparent + if (vE.a<0.002) return vX; - eq_D_QA = eq(D,QA); - eq_D_QG = eq(D,QG); eq_B_PC = eq(B,PC); + eq_B_PA = eq(B,PA); + eq_D_QG = eq(D,QG); + eq_D_QA = eq(D,QA); - // 3. Half-dithering (usually silhouette shading) - weak blend + // Subsequent two checks do not need Eisblack + // 3. Half-dithering - usually shadow expression on outline edges, use weak blending if ( comboE3 && comboA3 && (eq_B_PC || eq_D_QG) && eq_D_QA && eq_B_PA) { return mixok ? Mix618off : Mix854off; } - // 4. Quarter-dithering (prevents ugly "finger" artifacts - SF2 Guile plane, Cadillacs and Dinosaurs character select) + // 4. Quarter dithering - prone to ugly small tail effect (Guile's plane in SF2, character select screen in Cadillacs and Dinosaurs) if ( comboE3 && eq_A_P - && eq_B_PA &&eq_D_QA && eq_D_QG + && eq_B_PA && eq_D_QA && eq_D_QG && eq_E_H ) return mixok ? Mix618off : Mix854off; if ( comboE3 && eq_A_Q - && eq_B_PA &&eq_D_QA && eq_B_PC + && eq_B_PA && eq_D_QA && eq_B_PC && eq_E_F ) return mixok ? Mix618off : Mix854off; - // High priority: A-side 3-in-a-row (after dithering rules) + + // A-side three-pixel alignment, strong pattern (must come after dithering) if (comboA3) return Xoff; - // E-side 3-in-a-row (after comboA3) + // E-side three-pixel alignment (must come after comboA3) if (comboE3) return mixok ? Mix382off : Xoff; + eq_B_P = eq(B, P); + eq_D_Q = eq(D, Q); - // B-D long slope components - eq_B_P = eq(B,P); - eq_D_Q = eq(D,Q); - B_wall = eq_B_C && !eq_B_P; - B_tower = eq_B_P && !eq_B_C; - D_tower = eq_D_Q && !eq_D_G; - D_wall = eq_D_G && !eq_D_Q; + B_slope = eq_B_PC && !eq_B_P && !eq_B_C && !eq_B_PA; + D_slope = eq_D_QG && !eq_D_Q && !eq_D_G && !eq_D_QA; + + B_wall = eq_B_C && !eq_B_PC && !eq_B_P; // skip one misalignment check + D_wall = eq_D_G && !eq_D_QG && !eq_D_Q; // skip one misalignment check + + B_tower = eq_B_P && !eq_B_PC && !eq_B_C && !eq_B_PA; + D_tower = eq_D_Q && !eq_D_QG && !eq_D_G && !eq_D_QA; + + + if ( B_slope && eq_E_G ) return mixok ? Mix382off : Xoff; + if ( D_slope && eq_E_C ) return mixok ? Mix382off : Xoff; + + +// E-B-D regional chessboard scoring rules int scoreE = 0; int scoreB = 0; int scoreD = 0; int scoreZ = 0; - -// E/B/D Zone Checkerboard Scoring Rules - // E Zone - if (En3) { - scoreE += 1; - if (B_wall || B_tower || D_tower || D_wall) scoreZ = 1; - } - if (eq_E_C) { - scoreE += 1; - scoreE += int(eq_E_F); + scoreE += 1+int(eq(F,H))+int(B_slope); + scoreE -= int(all_eq2(E,P,PC)&&!D_wall); } if (eq_E_G) { - scoreE += 1; - scoreE += int(eq_E_H); - + scoreE += 1+int(eq(F,H))+int(D_slope); + scoreE -= int(all_eq2(E,Q,QG)&&!B_wall); } - if (scoreE==0) { - // Single line - if (eq_E_F ||eq_E_H) return theEXIT; + // Higher priority than rectangle + if ( B_slope && eq_A_Q || D_slope && eq_A_P) scoreE += 1; + + En3 = eq_E_F && eq_E_H; + + // Clear 4/6 rectangle - exit early, do not participate in final Z long slope judgment + if ( scoreE==0 && !mixok && En4square && eq(E,S)==eq(E,SI) && eq(E,R)==eq(E,RI) ) return theEXIT; + + // Single bar + if ( scoreE==0 && !En3 && neq(E,I) ) { + if ( B_wall && eq_E_F ) return theEXIT; + if ( D_wall && eq_E_H ) return theEXIT; } - if ( eq_F_H ) { - scoreE += 1; - if ( scoreZ==0 && B_wall && (eq(F,R) || eq(G,H) || eq(F,I)) ) scoreZ = 1; - if ( scoreZ==0 && D_wall && (eq(C,F) || eq(H,S) || eq(F,I)) ) scoreZ = 1; + // Lower priority than single bar + if ( B_slope && eq_A_P || D_slope && eq_A_Q ) scoreE += 1; + + if ( !En3 && eq(F,H) ) { + if (Eisblack) return slopeBAD; //Single black pixel + scoreE += int(B_slope&&neq(C,F))+int(D_slope&&neq(G,H)); + if ( B_wall && (eq(F,R) || eq(F,RC) || eq(G,H) || eq(F,I)) ) scoreZ = 1; + if ( D_wall && (eq(C,F) || eq(H,SG) || eq(H,S) || eq(F,I)) ) scoreZ = 1; } - #define Bn3 eq_B_P&&eq_B_C - #define Dn3 eq_D_G&&eq_D_Q - // B Zone - scoreB -= int(Bn3); - scoreB -= int(eq(C,P)); - if (scoreB < 0) scoreZ = 0; if (eq_B_PA) { - scoreB -= 1; - scoreB -= int(eq_B_P); // Replace eq(P,PA) + scoreB -= 1+int(eq(P,C))+int(eq_A_AA); } -// D Zone - scoreD -= int(Dn3); - scoreD -= int(eq(G,Q)); - if (scoreD < 0) scoreZ = 0; + if (eq(P,C)){ + scoreB -= int(eq_A_AA); + // Critical. Prevent Z scoring in clone patterns on this side caused only by F==H + // Equivalent: if (scoreE==0) scoreZ = 0; + scoreZ *= int(scoreE != 0); + } + +// D Zone if (eq_D_QA) { - scoreD -= 1; - scoreD -= int(eq_D_Q); // Replace eq(Q,QA) + scoreD -= 1+int(eq(G,Q))+int(eq_A_AA); + } + + if (eq(G,Q)){ + scoreD -= int(eq_A_AA); + // Same logic as B zone + scoreZ *= int(scoreE != 0); } int scoreFinal = scoreE + scoreB + scoreD + scoreZ ; - if (scoreE >= 1 && scoreB >= 0 && scoreD >=0) scoreFinal += 1; + if (scoreFinal >= 2) return vX; - if (scoreFinal >= 2) return colX; + if (scoreFinal == 1) return mixok ? Mix382 : vX; - if (scoreFinal == 1) return mixok ? Mix382 : colX; - - // Final: Zero score, no B/D penalties = long slope + // Final long slope pattern: total score zero, no deductions in B/D zones forms long slope if (scoreB >= 0 && scoreD >=0) { - if (B_wall&&D_tower) return colX; - if (B_tower&&D_wall) return colX; + if (B_wall&&D_tower) return vX; + if (B_tower&&D_wall) return vX; } return slopeBAD; -} // eq_E_A +} // E == A + +/*=============================================== + Main Rule: E - C - G + ========================================== zz */ + + if (eq_E_C ) { + if (comboA3) return vX; + if (comboE3) return mixok ? Mix382 : vX; + if (all_eq2(B,A,PA) && all_eq3(E,F,P,PC)) return theEXIT; + return mixok ? Mix382 : vX; + } + + if (eq_E_G) { + if (comboA3) return vX; + if (comboE3) return mixok ? Mix382 : vX; + if (all_eq2(D,A,QA) && all_eq3(E,H,Q,QG)) return theEXIT; + return mixok ? Mix382 : vX; + } /*========================================================= - F - H / B+ D+ Extension Rules + F - H / B+ D+ Extension New Rules ==================================================== zz */ -// This section is logically walled off from sim section by center E/en4square/BD -// So detection rules differ from sim side + // This section is the remainder after previous filtering; central En4square and BD are naturally wall-isolated logically + // B-D three-sided isolation? No longer needed after new "double slope rule" processing + // Experience 1: Hollow L(1+2) flattens inner side but not outer side + // Experience 2: "厂" shape edge flattens outer side but not inner side - eq_B_P = eq(B, P); - eq_B_PC = eq(B, PC); - eq_D_Q = eq(D, Q); - eq_D_QG = eq(D, QG); + // No need for subsequent calculation if E is hollow with no diagonal connection + if (vE.a<0.002) return theEXIT; - // Exit if B/D fully isolated (practical: required for this section) - if ( !eq_B_C && !eq_B_P && !eq_B_PC && !eq_D_G && !eq_D_Q && !eq_D_QG ) return slopeBAD; + bool eq_A_B = eq(A,B); + bool eq_F_H = eq(F,H); - mixok = E!=0u && mixcheck(colX,colE); - - // Exit if center E is isolated high-contrast pixel - // Tighten threshold if E is bright - float E_lumDiff = El > 0.92 ? 0.145898 : 0.381966; - // Large difference from neighbors - if ( !mixok && !eq_E_I && !EalphaL && distEC>0.0638587 && distEG>0.0638587&& abs(El-Fl)>E_lumDiff && abs(El-Hl)>E_lumDiff ) return slopeBAD; - - - eq_A_B = eq(A, B); - eq_A_P = eq(A, P); - eq_A_Q = eq(A, Q); - eq_B_PA = eq(B,PA); - eq_D_QA = eq(D,QA); - comboA3 = eq_A_P && eq_A_Q; - ThickBorder = eq_A_B && (eq_A_P||eq_A_Q|| eq(A,AA)&&(eq_B_PA||eq_D_QA)); - - if (ThickBorder && !Xisblack) mixok=false; + eq_B_P = eq(B,P); + eq_B_PC = eq(B,PC); + eq_B_PA = eq(B,PA); + eq_D_Q = eq(D,Q); + eq_D_QG = eq(D,QG); + eq_D_QA = eq(D,QA); B_slope = eq_B_PC && !eq_B_P && !eq_B_C; - B_tower = eq_B_P && !eq_B_PC && !eq_B_C && !eq_B_PA; D_slope = eq_D_QG && !eq_D_Q && !eq_D_G; + B_tower = eq_B_P && !eq_B_PC && !eq_B_C && !eq_B_PA; D_tower = eq_D_Q && !eq_D_QG && !eq_D_G && !eq_D_QA; + B_wall = eq_B_C && !eq_B_PC && !eq_B_P; + D_wall = eq_D_G && !eq_D_QG && !eq_D_Q; + +// 1. B-D Hollow slope if (!eq_A_B) { - // B + D + dual extension patterns - // Practical 1: Clear shape on one side = relaxed on other - // Practical 2: "厂" shape: flatten outer, not inner (tower allowed, wall not) - if ( (B_slope||B_tower) && (eq_D_QG&&!eq_D_G||D_tower) ) return Xoff; - if ( (D_slope||D_tower) && (eq_B_PC&&!eq_B_C||B_tower) ) return Xoff; - // High priority: A-side 3-in-a-row - // Note: comboA3 only valid with !eq_A_B in this section + // A-side three-pixel alignment, high priority + // Note: comboA3 cannot be used without A!=B in this section if (comboA3) return Xoff; - // 2x2 combo supplement + if ( (B_slope||B_tower) && (D_slope||D_tower) ) return Xoff; + if ( B_slope && eq_A_P ) return mixok ? Mix382off : Xoff; if ( D_slope && eq_A_Q ) return mixok ? Mix382off : Xoff; + + if ( (B_slope || D_slope) && eq_F_H ) return mixok ? Mix382off : Xoff; + + if ( B_slope && eq(H,SG) ) return mixok ? Mix382off : Xoff; + if ( D_slope && eq(F,RC) ) return mixok ? Mix382off : Xoff; + + if ( B_slope && eq_A_Q && eq(Q,QG) ) return mixok ? Mix382off : Xoff; + if ( D_slope && eq_A_P && eq(P,PC) ) return mixok ? Mix382off : Xoff; + } - B_wall = eq_B_C && !eq_B_PC && !eq_B_P; - - // Clear long slope (non-solid edge - strong trend!) - // Special condition for long slopes - if ( B_wall && D_tower ) { - if (eq_A_B ) return slopeBAD; - if (eq_E_F ) return colX; // WIP: Test direct X no blend - return mixok ? Mix382off : Xoff; - } - - D_wall = eq_D_G && !eq_D_QG&& !eq_D_Q; - - if ( B_tower && D_wall ) { - if (eq_A_B ) return slopeBAD; - if (eq_E_H ) return colX; - return mixok ? Mix382off : Xoff; - } - - // No need for hollow E processing beyond this point - if (E==0u) return theEXIT; - // sim3 has no fully transparent input - bool sim_X_E = sim3(colX,colE); - bool eq_G_H = eq(G, H); - bool eq_C_F = eq(C, F); - bool eq_H_S = eq(H, S); - bool eq_F_R = eq(F, R); - - En3 = eq_E_F&&eq_E_H; - - // Wall-enclosed 4-pixel rectangle (En4square) - if ( En4square ) { // Square check MUST come after previous rule - if (sim_X_E) return mixok ? Mix382off : Xoff; - // Exit solid L-enclosure (fixes font corners & unrounded building edges - Mega Man 7) - if ( (eq_B_C || eq_D_G) && eq_A_B ) return theEXIT; - // Independent clear 4/6-pixel rectangle (check rectangle edges) - if ( ( eq_B_C&&!eq_G_H || eq_D_G&&!eq_C_F || !eq_G_H&&!eq_C_F&&diffEB>0.5) && (eq_H_S == eq(I, SI) && eq_F_R == eq(I, RI)) ) return theEXIT; - - return mixok ? Mix382off : Xoff; - } - - // Wall-enclosed triangle - if ( En3 ) { - if (sim_X_E) return mixok ? Mix382off : Xoff; - if (eq_H_S && eq_F_R) return theEXIT; // Dual extension (building edges) - // Inner bend - if (eq_B_C || eq_D_G) return mixok ? Mix382off : Xoff; - // Return directly if thick (Z-snake flattens below outer bends) - if (eq_A_B) return mixok ? Mix382off : Xoff; - // Outer bend - if (eq_B_P || eq_D_Q) return theEXIT; - - return mixok ? Mix382off : Xoff; - // Empirical rules: connect inner L bends, not outer (Double Dragon Jimmy eyebrows) - } - - // F - H - // Rule: connect inner L bends, not outer - if ( eq_F_H ) { - if (sim_X_E||EalphaL) return mixok ? Mix382off : Xoff; - // Exit solid L-enclosure (prevents dual symmetric crushing of single pixels) - if ( eq_B_C && eq_A_B && (eq_G_H||!eq_F_R) &&eq(F, I) ) return slopeBAD; - if ( eq_D_G && eq_A_B && (eq_C_F||!eq_H_S) &&eq(F, I) ) return slopeBAD; - - // Inner bend - if (eq_B_C && (eq_F_R||eq_G_H||eq(F, I))) return mixok ? Mix382off : Xoff; - if (eq_D_G && (eq_C_F||eq_H_S||eq(F, I))) return mixok ? Mix382off : Xoff; - // Break trend: E-I F-H cross - if (eq_E_I) return slopeBAD; - // Z-shape outer - if (eq_B_P && eq_A_B) return mixok ? Mix382off : Xoff; - if (eq_D_Q && eq_A_B) return mixok ? Mix382off : Xoff; - // Outer bend unless opposite forms long L-trend - if (eq_B_P && (eq_C_F&&eq_H_S)) return mixok ? Mix382off : Xoff; - if (eq_D_Q && (eq_F_R&&eq_G_H)) return mixok ? Mix382off : Xoff; - - return slopeBAD; - } - // Final long slope cleanup (non-clear shapes) - // Note: Different cleanup from sim2 section - exit solid corners - if ( eq_B_C && eq_D_Q || eq_D_G && eq_B_P) { - // Critical: exit eq_A_B first (prevents corner pixel clipping - Eternal Secrets) - if (eq_A_B) return theEXIT; + bool sim_EC = sim(vE, vC); + bool sim_EG = sim(vE, vG); + + // Exit if center E is a single high-contrast pixel + // Tighten threshold for bright E + float E_lumDiff = mix(0.381966, 0.145898, max((El - 0.854102),0.0) * 6.8541); + + // Large difference from surroundings (lower priority than slope detection) + if ( !mixok && !sim_EC && !sim_EG && E.a>0.381966 && neq(E,I) && abs(El-Fl)>E_lumDiff && abs(El-Hl)>E_lumDiff ) return slopeBAD; + + + eq_E_F = eq(E,F); + eq_E_H = eq(E,H); + + // Long slope special trend + // Note: Allow squares, hand over to En4square judgment later + if ( eq_B_C && eq_D_Q ) { + if ( eq(P,PC) && eq(A,QA) && !eq_D_QG && eq_E_F && !eq_E_H && eq(H,I)) return theEXIT; + if ( eq_A_B ) return slopeBAD; + if ( B_wall && D_tower && eq_E_F) return vX; return mixok ? Mix382off : Xoff; } - // Final B+D dual extension catch (higher priority than L inner/outer lines) - if ( (B_slope||B_tower) && (eq_D_QG&&!eq_D_G||D_tower) ) return Xoff; - if ( (D_slope||D_tower) && (eq_B_PC&&!eq_B_C||B_tower) ) return Xoff; - - - // Exit for clear L-notch inner line (not even sim_X_E exempt) - if (eq_A_B && !ThickBorder && !eq_E_I ) { - - if (B_wall && eq_E_F) return theEXIT; - if (D_wall && eq_E_H) return theEXIT; + if ( eq(D,G) && eq(B,P)) { + if ( eq(Q,QG) && eq(A,PA) && !eq_B_PC && eq_E_H && !eq_E_F && eq(F,I)) return theEXIT; + if ( eq_A_B ) return slopeBAD; + if ( B_tower && D_wall && eq_E_H) return vX; + return mixok ? Mix382off : Xoff; } -if (sim_X_E||EalphaL) return mixok ? Mix382off : Xoff; - // Exit for hollow L-corner outer line (connect inner, not outer) - // Practical: Prevents font edge clipping (Cadillacs and Dinosaurs) - if ( (B_tower || D_tower) && (eq_E_F||eq_E_H) && !eq_A_B && !eq_E_I) return theEXIT; - // Final B/D single extension checks + En3 = eq_E_F && eq_E_H; - // Max slope range - if ( B_slope && !eq_A_B && eq(PC,CC) && noteq(PC,RC)) return mixok ? Mix382off : Xoff; - if ( D_slope && !eq_A_B && eq(QG,GG) && noteq(QG,SG)) return mixok ? Mix382off : Xoff; - - // Relaxed slope check if X/E similar (with internal constraints) - if ( mixok && !eq_A_B ) { - if ( B_slope && (!eq_C_F||eq(F,RC)) ) return Mix382off; - if ( D_slope && (!eq_G_H||eq(H,SG)) ) return Mix382off; + // Wall-enclosed 4-pixel square (En3 && eq(E,I)) + if ( En4square ) { // This square check must come after the previous rule + // Exit for solid L enclosure (some font edges, building corners) + // L enclosure (corner hollow) / high-contrast independent clear 4-pixel square / 6-pixel rectangle + if ( ( eq_B_C || eq_D_G) && eq_A_B) return theEXIT; + if ( ( eq_B_C || eq_D_G || !mixok) && (eq(E,S) == eq(E, SI) && eq(E,R) == eq(E, RI)) ) return theEXIT; + return mixok ? Mix382off : Xoff; } - // Exclude single lines before Z-snake (required) - if ((eq_E_F||eq_E_H) && !eq_E_I ) return theEXIT; + // + if (vE.a<0.381966) return mixok ? Mix382off : Xoff; - // Z-snake (thick eq_A_B, one side tower/wall, other not) - if ( eq_B_P && !eq_B_PA && !eq_D_Q && eq_A_B) return mixok ? Mix382off : Xoff; - if ( eq_D_Q && !eq_D_QA && !eq_B_P && eq_A_B) return mixok ? Mix382off : Xoff; + // BD-side solid non-wall pattern + if (!eq_B_C && !eq_D_G ) { + // B/D side semi-solid 1 - F-H required + if ( comboA3 && eq_F_H ) return Xoff; - return theEXIT; + // B/D side semi-solid 2 (with "definite rounding" trend judgment) + if ( comboA3&&eq_B_PC&&eq(C,CC) ) return Xoff; + if ( comboA3&&eq_D_QG&&eq(G,GG) ) return Xoff; + + // B/D three-sided isolation and non-En3 - exit (practice: required for this branch) + if ( !eq_B_P && !eq_B_PC && !eq_D_Q && !eq_D_QG && !En3 ) return slopeBAD; + + // 3 diagonal gradients after excluding the above + if (eq_A_Q&&sim_EC) return mixok ? Mix382off : Xoff; + if (eq_A_P&&sim_EG) return mixok ? Mix382off : Xoff; + if (sim_EC&&sim_EG ) return mixok ? Mix382off : Xoff; +} + + // Wall-enclosed triangle + if ( En3 ) return theEXIT; + + // F - H + // Principle: Connect L inner curve, not L outer curve + if (eq_F_H) { + + // F-H three-pixel pattern, huge improvement! Prioritize over A==B + if ( eq_B_PC&&eq(F,RC) || eq_D_QG&&eq(H,SG) ) return mixok ? Mix382off : Xoff; + + if (eq_A_B) return slopeBAD; + + if ( eq_B_C || eq_D_G) return mixok ? Mix382off : Xoff; + if ( eq_B_PC || eq_D_QG) return mixok ? Mix382off : Xoff; + + } + + return slopeBAD; } // admixX -vec4 admixS(uint A, uint B, uint C, uint D, uint E, uint F, uint G, uint H, uint I, uint R, uint RC, uint RI, uint S, uint SG, uint SI, uint II, bool eq_B_D, bool eq_E_D, float El, float Bl, vec4 colE, vec4 colF) { - // A B C . - // Q D 🄴 🅵 🅁 Zone 4 - // 🅶 🅷 I - // S - // Practical 1: sim E/B(C) follows original logic - no jarring saw insertion on single-pixel E - // Practical 2: E can equal I? YES! +vec4 admixS( vec4 A, vec4 B, vec4 C, vec4 D, vec4 E, vec4 F, vec4 G, vec4 H, vec4 I + , vec4 R, vec4 RC, vec4 RI, vec4 S, vec4 SG, vec4 SI, vec4 II + //, vec4 vE, vec4 vF, vec4 vC + ) { - if (any_eq2(F,C,I)) return colE; - //if (any_eq3(F,A,C,I)) return colE; + // A B C . + // QD 🄴 🅵 🆁 Zone 4 + // 🅶 🅷 I + // S + // Practice 1: sim(E,B/C) follows original logic; no abruptness when E is single pixel inserted by saw in practice + // Experience 2: E can equal I - if (eq(R, RI) && noteq(R,I)) return colE; - if (eq(H, S) && noteq(H,I)) return colE; + if (any_eq2(F,C,I)) return vE; - if ( eq(R, RC) || eq(G,SG) ) return colE; + if (eq(R, RI) && neq(R,I)) return vE; + if (eq(H, S) && neq(H,SI)) return vE; + if (eq(I, SI) && neq(I,S) ) return vE; - // Remove alpha channel weighting - Bl = fract(Bl) *10.0; - El = fract(El) *10.0; + if ( eq(R, RC) || eq(G,SG) ) return vE; + // Necessary condition for opposite trend judgment + if ( none_eq2(I,H,S) && (SI!=RI || I==II) ) return vE; - if ( ( eq_B_D&&eq(B,C)&&diffEB<0.381966 || eq_E_D&&vi_sim2(colE,E,C) ) && - (any_eq3(I,H,S,RI) || eq(SI,RI)&¬eq(I,II)) ) return colF; + if ( eq(E,C) && (eq(E,D)||eq(B,D)) ) return vF; - return colE; + if ( eq(E,D) && eq(B,C) && sim(vE,vC) ) return vF; + + bool mixok = vE.a>0.002 && mixcheck(vF,vE); + if ( all_eq2(B,C,D) && fastcheck(vE, vC) ) return mixok ? mix(vF,vE,0.381966) : vF; + + return vE; } - -//////////////////////////////////////////// main line /////////////////////////////////////////////// pin zz +////////////////////////////////////////////////////////////////////////////////////////////////////////// zz void applyScaling(uvec2 xy) { int srcX = int(xy.x); int srcY = int(xy.y); - ivec2 destXY = ivec2(xy) * 2; - uint E = src(srcX, srcY); - uint B = src(srcX, srcY-1); - uint D = src(srcX-1, srcY); - uint F = src(srcX+1, srcY); - uint H = src(srcX, srcY+1); + vec4 E = src(srcX, srcY); + vec4 B = src(srcX, srcY-1); + vec4 D = src(srcX-1, srcY); + vec4 F = src(srcX+1, srcY); + vec4 H = src(srcX, srcY+1); - vec4 colE = unpackUnorm4x8(E); - vec4 J = colE, K = colE, L = colE, M = colE; + vec4 J = E, K = E, L = E, M = E; bool eq_E_D = eq(E,D); bool eq_E_F = eq(E,F); bool eq_E_B = eq(E,B); bool eq_E_H = eq(E,H); - -// Skip horizontal/vertical 3x1 lines -if ( eq_E_D && eq_E_F || eq_E_B && eq_E_H) {writeJKLM;return;} - bool eq_B_H = eq(B,H); bool eq_D_F = eq(D,F); -// Skip if center enclosed by mirror pixels -if ( eq_B_H && eq_D_F ) {writeJKLM;return;} - // Fetch 5x5 neighborhood - uint A = src(srcX-1, srcY-1); - uint C = src(srcX+1, srcY-1); - uint G = src(srcX-1, srcY+1); - uint I = src(srcX+1, srcY+1); - uint P = src(srcX, srcY-2); - uint Q = src(srcX-2, srcY); - uint R = src(srcX+2, srcY); - uint S = src(srcX, srcY+2); +// Skip horizontal/vertical 3x1 lines +bool skiprest = (eq_E_D && eq_E_F) || (eq_E_B && eq_E_H) || (eq_B_H && eq_D_F); +if (!skiprest) { - uint PA = src(srcX-1, srcY-2); - uint PC = src(srcX+1, srcY-2); - uint QA = src(srcX-2, srcY-1); - uint QG = src(srcX-2, srcY+1); // AA PA [P] PC CC - uint RC = src(srcX+2, srcY-1); // ┌──┬──┬──┐ - uint RI = src(srcX+2, srcY+1); // QA │ A │ B │ C │ RC - uint SG = src(srcX-1, srcY+2); // ├──┼──┼──┤ - uint SI = src(srcX+1, srcY+2); // [Q] │ D │ E │ F │ [R] - uint AA = src(srcX-2, srcY-2); // ├──┼──┼──┤ - uint CC = src(srcX+2, srcY-2); // QG │ G │ H │ I │ RI - uint GG = src(srcX-2, srcY+2); // └──┴──┴──┘ - uint II = src(srcX+2, srcY+2); // GG SG [S] SI II + //Fetch 5x5 pixels + vec4 A = src(srcX-1, srcY-1); + vec4 C = src(srcX+1, srcY-1); + vec4 G = src(srcX-1, srcY+1); + vec4 I = src(srcX+1, srcY+1); + vec4 P = src(srcX, srcY-2); + vec4 Q = src(srcX-2, srcY); + vec4 R = src(srcX+2, srcY); + vec4 S = src(srcX, srcY+2); -// Unpack 8 neighbors - vec4 colA = unpackUnorm4x8(A); - vec4 colC = unpackUnorm4x8(C); - vec4 colG = unpackUnorm4x8(G); - vec4 colI = unpackUnorm4x8(I); - vec4 colB = unpackUnorm4x8(B); - vec4 colD = unpackUnorm4x8(D); - vec4 colF = unpackUnorm4x8(F); - vec4 colH = unpackUnorm4x8(H); + vec4 PA = src(srcX-1, srcY-2); + vec4 PC = src(srcX+1, srcY-2); + vec4 QA = src(srcX-2, srcY-1); + vec4 QG = src(srcX-2, srcY+1); // AA PA [P] PC CC + vec4 RC = src(srcX+2, srcY-1); // ┌──┬──┬──┐ + vec4 RI = src(srcX+2, srcY+1); // QA │ A │ B │ C │ RC + vec4 SG = src(srcX-1, srcY+2); // ├──┼──┼──┤ + vec4 SI = src(srcX+1, srcY+2); // [Q] │ D │ E │ F │ [R] + vec4 AA = src(srcX-2, srcY-2); // ├──┼──┼──┤ + vec4 CC = src(srcX+2, srcY-2); // QG │ G │ H │ I │ RI + vec4 GG = src(srcX-2, srcY+2); // └──┴──┴──┘ + vec4 II = src(srcX+2, srcY+2); // GG SG [S] SI II + // Precompute luminance - float Bl = luma(colB); - float Dl = luma(colD); - float El = luma(colE); - float Fl = luma(colF); - float Hl = luma(colH); + float Bl = luma(vB); + float Dl = luma(vD); + float El = luma(vE); + float Fl = luma(vF); + float Hl = luma(vH); -// Pre-calculate +// Pre-calibration bool eq_B_D = eq(B,D); bool eq_B_F = eq(B,F); bool eq_D_H = eq(D,H); bool eq_F_H = eq(F,H); - bool eq_E_A = eq(E, A); - bool eq_E_C = eq(E, C); - bool eq_E_G = eq(E, G); - bool eq_E_I = eq(E, I); - // Any mirror enclosure of center + // Any mirrored block encloses center pixel bool oppoPix = eq_B_H || eq_D_F; - // Flags for 1:1 slope processing + // Flag for pixels caught by 1:1 slope rule and entered admixX function bool slope1 = false; bool slope2 = false; bool slope3 = false; bool slope4 = false; - // Valid standard pixel return from 1:1 slope + // Standard pixels that passed 1:1 slope rule and returned normally bool slope1ok = false; bool slope2ok = false; bool slope3ok = false; bool slope4ok = false; - // slopeBAD: entered admixX but returned E (at least one of JKLM) - // slopOFF: returned with OFF flag - skip long slope processing + // slopeBAD: entered admixX but (at least one of JKLM) returned E point + // slopOFF: returned with OFF flag, no long slope calculation later - // B - D - if ( (!eq_E_B&&!eq_E_D&&!oppoPix) && (!eq_D_H&&!eq_B_F) && (B!=0u&&D!=0u) && - (eq_E_A || El>=Dl&&El>=Bl) && ( (El 1.0 ) { - if (J.b > 7.0 ) J=J-8.0; // slopOFF - if (J.b == 4.0 ) { - J=colE; - writeJKLM; - return; - } - if (J.b == 2.0 ) J=colE; // slopeBAD - } else slope1ok = true; + +// B - D + if ( (vB.a>0.002 && vD.a>0.002) && + (!eq_E_B && !eq_E_D && !oppoPix) && (!eq_D_H && !eq_B_F) + && (eq(E,A) || El>=Dl&&El>=Bl) && ( (El 7.1); // theEXIT + J = (J.b > 3.1) ? vE : // Restore vE for slopeBAD/theEXIT + (J.b > 1.1) ? (J - 2.0) :// slopeoff + J; // Normal pixel [0-1.0] } - // B - F - if ( !slope1 && - (!eq_E_B&&!eq_E_F&&!oppoPix) && (!eq_B_D&&!eq_F_H) && (B!=0u&&F!=0u) && - (eq_E_C || El>=Bl&&El>=Fl) && ( (El0.002 && vF.a>0.002) + && (!eq_E_B && !eq_E_F && !oppoPix) && (!eq_B_D && !eq_F_H) + && (eq(E,C) || El>=Bl&&El>=Fl) && ( (El 1.0 ) { - if (K.b > 7.0 ) K=K-8.0; - if (K.b == 4.0 ) { - K=colE; - writeJKLM; - return; - } - if (K.b == 2.0 ) K=colE; - } else {slope2ok = true;} + slope2ok = (K.b < 1.1); + skiprest = (K.b > 7.1); + K = (K.b > 3.1) ? vE : + (K.b > 1.1) ? (K - 2.0) : + K; } - // D - H - if ( !slope1 && - (!eq_E_D&&!eq_E_H&&!oppoPix) && (!eq_F_H&&!eq_B_D) && (D!=0u&&H!=0u) && - (eq_E_G || El>=Hl&&El>=Dl) && ((El0.002 && vH.a>0.002) + && (!eq_E_D && !eq_E_H && !oppoPix) && (!eq_F_H && !eq_B_D) + && (eq(E,G) || El>=Hl&&El>=Dl) && ((El 1.0 ) { - if (L.b > 7.0 ) L=L-8.0; - if (L.b == 4.0 ) { - L=colE; - writeJKLM; - return; - } - if (L.b == 2.0 ) L=colE; - } else {slope3ok = true;} + slope3ok = (L.b < 1.1); + skiprest = (L.b > 7.1); + L = (L.b > 3.1) ? vE : + (L.b > 1.1) ? (L - 2.0) : + L; } - // F - H - if ( !slope2 && !slope3 && - (!eq_E_F&&!eq_E_H&&!oppoPix) && (!eq_B_F&&!eq_D_H) && (F!=0u&&H!=0u) && - (eq_E_I || El>=Fl&&El>=Hl) && ((El0.002 && vH.a>0.002) + && (!eq_E_F && !eq_E_H && !oppoPix) && (!eq_B_F && !eq_D_H) + && (eq(E,I) || El>=Fl&&El>=Hl) && ((El 1.0 ) { - if (M.b > 7.0 ) M=M-8.0; - if (M.b == 4.0 ) { - M=colE; - writeJKLM; - return; - } - if (M.b == 2.0 ) M=colE; - } else {slope4ok = true;} + slope4ok = (M.b < 1.1); + skiprest = (M.b > 7.1); + M = (M.b > 3.1) ? vE : + (M.b > 1.1) ? (M - 2.0) : + M; } -// Long gentle 2:1 slope (P100) +// long gentle 2:1 slope (P100) - bool longslope = false; + if (slope4ok) { //zone4 long slope + // Original rule extension 1: pass adjacent pixel comparison as 3rd parameter in admixL to prevent double blending + // Original rule extension 2: no L pattern can reappear within opposite pixel interval unless forming a wall + if (all_eq2(R,F,G) && neq(R, RC) && (neq(Q,G)||eq(Q, QA))) {L=admixL(M,L,vH); skiprest = true;} + // vertical + if (all_eq2(S,H,C) && neq(S, SG) && (neq(P,C)||eq(P, PA))) {K=admixL(M,K,vF); skiprest = true;} + } - if (slope4ok && eq_F_H) { // Zone 4 long slope - // Original rule ext 1: Pass adjacent pixel to admixL to prevent double-blend - // Original rule ext 2: No L-shape within opposite pixel gap unless wall formed - if (eq(G,H) && eq(F,R) && noteq(R, RC) && (noteq(Q,G)||eq(Q, QA))) {L=admixL(M,L,colH); longslope = true;} - // Vertical - if (eq(C,F) && eq(H,S) && noteq(S, SG) && (noteq(P,C)||eq(P, PA))) {K=admixL(M,K,colF); longslope = true;} + if (slope3ok) { //zone3 long slope + // horizontal + if (all_eq2(Q,D,I) && neq(Q, QA) && (neq(R,I)||eq(R, RC))) {M=admixL(L,M,vH); skiprest = true;} + // vertical + if (all_eq2(S,H,A) && neq(S, SI) && (neq(A,P)||eq(P, PC))) {J=admixL(L,J,vD); skiprest = true;} + } + + if (slope2ok) { //zone2 long slope + // horizontal + if (all_eq2(R,F,A) && neq(R, RI) && (neq(A,Q)||eq(Q, QG))) {J=admixL(K,J,vB); skiprest = true;} + // vertical + if (all_eq2(P,B,I) && neq(P, PA) && (neq(I,S)||eq(S, SG))) {M=admixL(K,M,vF); skiprest = true;} + } + + if (slope1ok) { //zone1 long slope + // horizontal + if (all_eq2(Q,D,C) && neq(Q, QG) && (neq(C,R)||eq(R, RI))) {K=admixL(J,K,vB); skiprest = true;} + // vertical + if (all_eq2(P,B,G) && neq(P, PC) && (neq(G,S)||eq(S, SI))) {L=admixL(J,L,vD); skiprest = true;} + } + +// Long slope formed can exit; basically no sawslope formed on diagonal +// Note: sawslope cannot exclude slopeOFF (minority) and slopeBAD (very few), but can exclude slopeok (strong pattern) +if (!skiprest && !oppoPix && !slope1ok && !slope2ok && !slope3ok && !slope4ok) { + + + // horizontal bottom + if (!eq_E_H && none_eq2(H,A,C)) { + + // A B C ・ + // Q D 🄴 🅵 🆁 Zone 4 + // 🅶🅷 I + // S + // (!slope3 && neq(D,H)) clever combined check + if ( (!slope2 && !eq_B_F) && (!slope3 && !eq_D_H) && !eq_F_H && vF.a>0.002 && + !eq_E_F && eq(R,H) && eq(F,G) ) { + M = admixS( A, B, C, D, E, F, G, H, I + , R, RC, RI, S, SG, SI, II + //, vE, vF, vC + ); + skiprest = true;} + + // ・ A B C + // 🆀 🅳 🄴 F R Zone 3 + // G 🅷 🅸 + // S + if ( !skiprest && (!slope1 && !eq_B_D) && (!slope4 && !eq_F_H) && !eq_D_H && vD.a>0.002 && + !eq_E_D && eq(Q,H) && eq(D,I) ) { + L = admixS( C, B, A, F, E, D, I, H, G + , Q, QA, QG, S, SI, SG, GG + //, vE, vD, vA + ); + skiprest = true;} } + // horizontal up + if ( !skiprest && !eq_E_B && none_eq2(B,G,I)) { + + // P + // 🅐 🅑 C + // QD 🄴 🅵 🆁 Zone 2 + // G H I . + if ( (!slope1 && !eq_B_D) && (!slope4 && !eq_F_H) && !eq_B_F && vF.a>0.002 && + !eq_E_F && eq(B,R) && eq(A,F) ) { + K = admixS( G, H, I, D, E, F, A, B, C + , R, RI, RC, P, PA, PC, CC + //, vE, vF, vI + ); + skiprest = true;} + + // P + // A 🅑 🅲 + // 🆀 🅳 🄴 F R Zone 1 + // . G H I + if ( !skiprest && (!slope2 && !eq_B_F) && (!slope3 && !eq_D_H) && !eq_B_D && vD.a>0.002 && + !eq_E_D && eq(B,Q) && eq(C,D) ) { + J = admixS( I, H, G, F, E, D, C, B, A + , Q, QG, QA, P, PC, PA, AA + //, vE, vD, vG + ); + skiprest = true;} - if (slope3ok && eq_D_H) { // Zone 3 long slope - // Horizontal - if (eq(D,Q) && eq(H,I) && noteq(Q, QA) && (noteq(R,I)||eq(R, RC))) {M=admixL(L,M,colH); longslope = true;} - // Vertical - if (eq(A,D) && eq(H,S) && noteq(S, SI) && (noteq(A,P)||eq(P, PC))) {J=admixL(L,J,colD); longslope = true;} } - if (slope2ok && eq_B_F) { // Zone 2 long slope - // Horizontal - if (eq(A,B) && eq(F,R) && noteq(R, RI) && (noteq(A,Q)||eq(Q, QG))) {J=admixL(K,J,colB); longslope = true;} - // Vertical - if (eq(F,I) && eq(B,P) && noteq(P, PA) && (noteq(I,S)||eq(S, SG))) {M=admixL(K,M,colF); longslope = true;} + // vertical left + if ( !skiprest && !eq_E_D && none_eq2(D,C,I) ) { + + // 🅐 B C + // Q 🅳 🄴 F R + // G 🅷 I Zone 3 + // 🆂 ・ + if ( (!slope1 && !eq_B_D) && (!slope4 && !eq_F_H) && !eq_D_H && vH.a>0.002 && + !eq_E_H && eq(D,S) && eq(A,H) ) { + L = admixS( C, F, I, B, E, H, A, D, G + , S, SI, SG, Q, QA, QG, GG + //, vE, vH, vI + ); + skiprest = true;} + + // 🅟 ・ + // A 🅑 C + // Q 🅳 🄴 F R Zone 1 + // 🅶 HI + if ( !skiprest && (!slope3 && !eq_D_H) && (!slope2 && !eq_B_F) && !eq_B_D && vB.a>0.002 && + !eq_E_B && eq(P,D) && eq(B,G) ) { + J = admixS( I, F, C, H, E, B, G, D, A + , P, PC, PA, Q, QG, QA, AA + //, vE, vB, vC + ); + skiprest = true;} + } - if (slope1ok && eq_B_D) { // Zone 1 long slope - // Horizontal - if (eq(B,C) && eq(D,Q) && noteq(Q, QG) && (noteq(C,R)||eq(R, RI))) {K=admixL(J,K,colB); longslope = true;} - // Vertical - if (eq(D,G) && eq(B,P) && noteq(P, PC) && (noteq(G,S)||eq(S, SI))) {L=admixL(J,L,colD); longslope = true;} - } + // vertical right + if ( !skiprest && !eq_E_F && none_eq2(F,A,G) ) { // right -// Long slope formed = exit (rare diagonal sawslope) -bool skiprest = longslope; + // A B 🅲 + // Q D 🄴 🅵 R + // G 🅷 I Zone 4 + // . 🆂 + if ( (!slope2 && !eq_B_F) && (!slope3 && !eq_D_H) && !eq_F_H && vH.a>0.002 && + !eq_E_H && eq(S,F) && eq(H,C) ) { + M = admixS( A, D, G, B, E, H, C, F + , I, S, SG, SI, R, RC, RI, II + //, vE, vH, vG + ); + skiprest = true;} -bool slopeok = slope1ok||slope2ok||slope3ok||slope4ok; + // ・ 🅟 + // A 🅑 C + // Q D 🄴 🅵 R Zone 2 + // G H 🅸 + if ( !skiprest && (!slope1 && !eq_B_D) && (!slope4 && !eq_F_H) && !eq_B_F && vB.a>0.002 && + !eq_E_B && eq(P,F) && eq(B,I) ) { + K = admixS( G, D, A, H, E, B, I, F, C + , P, PA, PC, R, RI, RC, CC + //, vE, vB, vA + ); + skiprest = true;} - -// Note: sawslope cannot exclude slopeOFF (minor) / slopeBAD (rare), but CAN exclude slopeok (strong shapes) -if (!skiprest && !oppoPix && !slopeok) { - - - // Horizontal bottom - if (!eq_E_H && none_eq2(H,A,C)) { - - // A B C ・ - // Q D 🄴 🅵 🅁 Zone 4 - // 🅶 🅷 I - // S - // (!slope3 && !eq_D_H) chain is elegant - if ( (!slope2 && !eq_B_F) && (!slope3 && !eq_D_H) && !eq_F_H && F!=0u && - !eq_E_F && (eq_B_D || eq_E_D) && eq(R,H) && eq(F,G) ) { - M = admixS(A,B,C,D,E,F,G,H,I,R,RC,RI,S,SG,SI,II,eq_B_D,eq_E_D,El,Bl,colE,colF); - skiprest = true;} - - // ・ A B C - // 🆀 🅳 🄴 F R Zone 3 - // G 🅷 🅸 - // S - if ( !skiprest && (!slope1 && !eq_B_D) && (!slope4 && !eq_F_H) && !eq_D_H && D!=0u && - !eq_E_D && (eq_B_F || eq_E_F) && eq(Q,H) && eq(D,I) ) { - L = admixS(C,B,A,F,E,D,I,H,G,Q,QA,QG,S,SI,SG,GG,eq_B_F,eq_E_F,El,Bl,colE,colD); - skiprest = true;} - } - - // Horizontal up - if ( !skiprest && !eq_E_B && none_eq2(B,G,I)) { - - // P - // 🅐 🅑 C - // QD 🄴 🅵 🅁 Zone 2 - // G H I . - if ( (!slope1 && !eq_B_D) && (!slope4 && !eq_F_H) && !eq_B_F && F!=0u && - !eq_E_F && (eq_D_H || eq_E_D) && eq(B,R) && eq(A,F) ) { - K = admixS(G,H,I,D,E,F,A,B,C,R,RI,RC,P,PA,PC,CC,eq_D_H,eq_E_D,El,Hl,colE,colF); - skiprest = true;} - - // P - // A 🅑 🅲 - // 🆀 🅳 🄴 F R Zone 1 - // . G H I - if ( !skiprest && (!slope2 && !eq_B_F) && (!slope3 && !eq_D_H) && !eq_B_D && D!=0u && - !eq_E_D && (eq_F_H || eq_E_F) && eq(B,Q) && eq(C,D) ) { - J = admixS(I,H,G,F,E,D,C,B,A,Q,QG,QA,P,PC,PA,AA,eq_F_H,eq_E_F,El,Hl,colE,colD); - skiprest = true;} - - } - - // Vertical left - if ( !skiprest && !eq_E_D && none_eq2(D,C,I) ) { - - // 🅐 B C - // Q 🅳 🄴 F R - // G 🅷 I Zone 3 - // 🆂 ・ - if ( (!slope1 && !eq_B_D) && (!slope4 && !eq_F_H) && !eq_D_H && H!=0u && - !eq_E_H && (eq_B_F || eq_E_B) && eq(D,S) && eq(A,H) ) { - L = admixS(C,F,I,B,E,H,A,D,G,S,SI,SG,Q,QA,QG,GG,eq_B_F,eq_E_B,El,Fl,colE,colH); - skiprest = true;} - - // 🅟 ・ - // A 🅑 C - // Q 🅳 🄴 F R Zone 1 - // 🅶 HI - if ( !skiprest && (!slope3 && !eq_D_H) && (!slope2 && !eq_B_F) && !eq_B_D && B!=0u && - !eq_E_B && (eq_F_H || eq_E_H) && eq(P,D) && eq(B,G) ) { - J = admixS(I,F,C,H,E,B,G,D,A,P,PC,PA,Q,QG,QA,AA,eq_F_H,eq_E_H,El,Fl,colE,colB); - skiprest = true;} - - } - - // Vertical right - if ( !skiprest && !eq_E_F && none_eq2(F,A,G) ) { // right - - // A B 🅲 - // Q D 🄴 🅵 R - // G 🅷 I Zone 4 - // . 🆂 - if ( (!slope2 && !eq_B_F) && (!slope3 && !eq_D_H) && !eq_F_H && H!=0u && - !eq_E_H && (eq_B_D || eq_E_B) && eq(S,F) && eq(H,C) ) { - M = admixS(A,D,G,B,E,H,C,F,I,S,SG,SI,R,RC,RI,II,eq_B_D,eq_E_B,El,Dl,colE,colH); - skiprest = true;} - - // ・ 🅟 - // A 🅑 C - // Q D 🄴 🅵 R Zone 2 - // G H 🅸 - if ( !skiprest && (!slope1 && !eq_B_D) && (!slope4 && !eq_F_H) && !eq_B_F && B!=0u && - !eq_E_B && (eq_D_H || eq_E_H) && eq(P,F) && eq(B,I) ) { - K = admixS(G,D,A,H,E,B,I,F,C,P,PA,PC,R,RI,RC,CC,eq_D_H,eq_E_H,El,Dl,colE,colB); - skiprest = true;} - - } // vertical right + } // vertical right } // sawslope -// sawslope formed = exit; legacy: skiprest||slopeBAD (uses slopeOFF/ok with weak effect) -skiprest = skiprest||slope1||slope2||slope3||slope4||E==0u||B==0u||D==0u||F==0u||H==0u; +// Sawslope formed can exit; old plan: skiprest||slopeBAD (still use slopeOFF (weak) and slopok (strong) with average effect) +skiprest = skiprest||slope1||slope2||slope3||slope4||vE.a<0.002||vB.a<0.002||vD.a<0.002||vF.a<0.002||vH.a<0.002; /************************************************** - Concave + Cross pattern (P100) + "Concave + Cross" Pattern (P100) *************************************************/ -// Cross distant uses similar pixels - useful for horizontal lines + aliasing / gradient text -// e.g. SF2III intro glowing text, SFZ3mix Japanese houses, Garou intro +// Use approximate pixels for cross star far end, useful for some horizontal line + jagged and layered gradient patterns. +// e.g. Glowing text in Street Fighter III 3rd Strike opening, Japanese-style houses in SFZ3Mix, opening of Garou: Mark of the Wolves - vec4 colX; // Temporary X +vec4 vX; // Temporary X - if (!skiprest && - BlFl) && neq(F,src(srcX+3, srcY)) ) {K=admixK(vF,K); M=K;skiprest=true;} // RIGHT +if (!skiprest && !eq_E_D&&eq_E_F&&eq_B_D&&eq_D_H && all_eq2(E,A,G) && (eq(E,R)||El>Dl) && neq(D,src(srcX-3, srcY)) ) {J=admixK(vD,J); L=J;skiprest=true;} // LEFT +if (!skiprest && !eq_E_H&&eq_E_B&&eq_D_H&&eq_F_H && all_eq2(E,G,I) && (eq(E,P)||El>Hl) && neq(H,src(srcX, srcY+3)) ) {L=admixK(vH,L); M=L;skiprest=true;} // BOTTOM +if (!skiprest && !eq_E_B&&eq_E_H&&eq_B_D&&eq_B_F && all_eq2(E,A,C) && (eq(E,S)||El>Bl) && neq(B,src(srcX, srcY-3)) ) {J=admixK(vB,J); K=J;} // TOP - // Final Exit - writeJKLM; +} + //final write + ivec2 destXY = ivec2(xy) * 2; + writeColorf(destXY, J); + writeColorf(destXY + ivec2(1, 0), K); + writeColorf(destXY + ivec2(0, 1), L); + writeColorf(destXY + ivec2(1, 1), M); }