- [Canvas] Fix flood fill, magic selector combine black and fully transparent pixels.

This commit is contained in:
Tanasart 2024-05-29 11:30:01 +07:00
parent 1274fc9405
commit 196daeb849
8 changed files with 177 additions and 109 deletions

View file

@ -77,7 +77,7 @@ event_inherited();
} }
if(preset_selecting == i) if(preset_selecting == i)
var _palRes = drawPaletteGrid(pal.palette, ui(16), yy + ui(28), ww, _gs, selector.current_color); var _palRes = drawPaletteGrid(pal.palette, ui(16), yy + ui(28), ww, _gs, { color : selector.current_color, mx : _m[0], my : _m[1] });
else else
drawPalette(pal.palette, ui(16), yy + ui(28), ww, ui(20)); drawPalette(pal.palette, ui(16), yy + ui(28), ww, ui(20));

View file

@ -190,7 +190,7 @@ event_inherited();
} }
if(palette_selecting == i) if(palette_selecting == i)
var _palRes = drawPaletteGrid(pal.palette, ui(16), yy + ui(28), ww, _gs); var _palRes = drawPaletteGrid(pal.palette, ui(16), yy + ui(28), ww, _gs, { mx : _m[0], my : _m[1] });
else else
drawPalette(pal.palette, ui(16), yy + ui(28), ww, ui(20)); drawPalette(pal.palette, ui(16), yy + ui(28), ww, ui(20));

View file

@ -2,13 +2,15 @@ function _ff_getPixel(_x, _y) { return buffer_read_at(_ff_buff, (_y * _ff_w + _x
function canvas_ff_fillable(colorBase, colorFill, _x, _y, _thres) { #region function canvas_ff_fillable(colorBase, colorFill, _x, _y, _thres) { #region
var c = _ff_getPixel(_x, _y); var c = _ff_getPixel(_x, _y);
var d = color_diff(colorBase, c, true, true); var d = color_diff_alpha(colorBase, c);
//print($"Checking [{_x}, {_y}]: {colorBase} - {c} : {_color_get_alpha(colorBase)} - {_color_get_alpha(c)} | {d}");
return d <= _thres && c != colorFill; return d <= _thres && c != colorFill;
} #endregion } #endregion
function canvas_flood_fill_scanline(_surf, _x, _y, _thres, _corner = false) { #region function canvas_flood_fill_scanline(_surf, _x, _y, _thres, _corner = false) { #region
var colorFill = CURRENT_COLOR; var colorFill = CURRENT_COLOR;
var colorBase = surface_getpixel_ext(_surf, _x, _y); var colorBase = int64(surface_getpixel_ext(_surf, _x, _y));
if(colorFill == colorBase) return; //Clicking on the same color as the fill color if(colorFill == colorBase) return; //Clicking on the same color as the fill color
@ -24,13 +26,15 @@ function canvas_flood_fill_scanline(_surf, _x, _y, _thres, _corner = false) { #r
var spanAbove, spanBelow; var spanAbove, spanBelow;
var thr = _thres * _thres; var thr = _thres * _thres;
var queue = ds_queue_create(); var qx = ds_queue_create();
ds_queue_enqueue(queue, [_x, _y]); var qy = ds_queue_create();
ds_queue_enqueue(qx, _x);
ds_queue_enqueue(qy, _y);
while(!ds_queue_empty(queue)) { while(!ds_queue_empty(qx)) {
var pos = ds_queue_dequeue(queue);
x1 = pos[0]; x1 = ds_queue_dequeue(qx);
y1 = pos[1]; y1 = ds_queue_dequeue(qy);
if(_ff_getPixel(x1, y1) == colorFill) continue; //Color in queue is already filled if(_ff_getPixel(x1, y1) == colorFill) continue; //Color in queue is already filled
@ -47,32 +51,47 @@ function canvas_flood_fill_scanline(_surf, _x, _y, _thres, _corner = false) { #r
buffer_write(_ff_buff, buffer_u32, _c); buffer_write(_ff_buff, buffer_u32, _c);
if(y1 > 0) { if(y1 > 0) {
if(_corner && x1 > 0 && canvas_ff_fillable(colorBase, colorFill, x1 - 1, y1 - 1, thr)) //Check top left pixel if(_corner && x1 > 0 && canvas_ff_fillable(colorBase, colorFill, x1 - 1, y1 - 1, thr)) { //Check top left pixel
ds_queue_enqueue(queue, [x1 - 1, y1 - 1]); ds_queue_enqueue(qx, x1 - 1);
ds_queue_enqueue(qy, y1 - 1);
}
if(canvas_ff_fillable(colorBase, colorFill, x1, y1 - 1, thr)) //Check top pixel if(canvas_ff_fillable(colorBase, colorFill, x1, y1 - 1, thr)) { //Check top pixel
ds_queue_enqueue(queue, [x1, y1 - 1]); ds_queue_enqueue(qx, x1);
ds_queue_enqueue(qy, y1 - 1);
}
} }
if(y1 < surface_h - 1) { if(y1 < surface_h - 1) {
if(_corner && x1 > 0 && canvas_ff_fillable(colorBase, colorFill, x1 - 1, y1 + 1, thr)) //Check bottom left pixel if(_corner && x1 > 0 && canvas_ff_fillable(colorBase, colorFill, x1 - 1, y1 + 1, thr)) { //Check bottom left pixel
ds_queue_enqueue(queue, [x1 - 1, y1 + 1]); ds_queue_enqueue(qx, x1 - 1);
ds_queue_enqueue(qy, y1 + 1);
}
if(canvas_ff_fillable(colorBase, colorFill, x1, y1 + 1, thr)) //Check bottom pixel if(canvas_ff_fillable(colorBase, colorFill, x1, y1 + 1, thr)) { //Check bottom pixel
ds_queue_enqueue(queue, [x1, y1 + 1]); ds_queue_enqueue(qx, x1);
ds_queue_enqueue(qy, y1 + 1);
}
} }
if(_corner && x1 < surface_w - 1) { if(_corner && x1 < surface_w - 1) {
if(y1 > 0 && canvas_ff_fillable(colorBase, colorFill, x1 + 1, y1 - 1, thr)) //Check top right pixel if(y1 > 0 && canvas_ff_fillable(colorBase, colorFill, x1 + 1, y1 - 1, thr)) { //Check top right pixel
ds_queue_enqueue(queue, [x1 + 1, y1 - 1]); ds_queue_enqueue(qx, x1 + 1);
ds_queue_enqueue(qy, y1 - 1);
}
if(y1 < surface_h - 1 && canvas_ff_fillable(colorBase, colorFill, x1 + 1, y1 + 1, thr)) //Check bottom right pixel if(y1 < surface_h - 1 && canvas_ff_fillable(colorBase, colorFill, x1 + 1, y1 + 1, thr)) { //Check bottom right pixel
ds_queue_enqueue(queue, [x1 + 1, y1 + 1]); ds_queue_enqueue(qx, x1 + 1);
ds_queue_enqueue(qy, y1 + 1);
}
} }
x1++; x1++;
} }
} }
ds_queue_destroy(qx);
ds_queue_destroy(qy);
draw_set_alpha(1); draw_set_alpha(1);
buffer_delete(_ff_buff); buffer_delete(_ff_buff);
@ -100,7 +119,7 @@ function canvas_flood_fill_all(_surf, _x, _y, _thres) { #region
for (var j = 0; j < _ff_w; j++) { for (var j = 0; j < _ff_w; j++) {
var c = buffer_read(_ff_buff, buffer_u32); var c = buffer_read(_ff_buff, buffer_u32);
var d = color_diff(colorBase, c, true, true); var d = color_diff_alpha(colorBase, c);
if(d > _thres) continue; if(d > _thres) continue;
draw_point(j, i); draw_point(j, i);

View file

@ -1,13 +1,13 @@
function canvas_ms_fillable(colorBase, colorFill, _x, _y, _thres) { #region function canvas_ms_fillable(colorBase, colorFill, _x, _y, _thres) { #region
var c = _ff_getPixel(_x, _y); var c = _ff_getPixel(_x, _y);
var d = color_diff(colorBase, c, true, true); var d = color_diff_alpha(colorBase, c);
return d <= _thres; return d <= _thres;
} #endregion } #endregion
function canvas_magic_selection_scanline(_surf, _x, _y, _thres, _corner = false) { #region function canvas_magic_selection_scanline(_surf, _x, _y, _thres, _corner = false) { #region
var colorBase = surface_getpixel_ext(_surf, _x, _y); var colorBase = int64(surface_getpixel_ext(_surf, _x, _y));
var colorFill = colorBase; var colorFill = colorBase;
var x1, y1, x_start; var x1, y1, x_start;
@ -19,8 +19,10 @@ function canvas_magic_selection_scanline(_surf, _x, _y, _thres, _corner = false)
_ff_buff = buffer_create(_ff_w * _ff_h * 4, buffer_fixed, 4); _ff_buff = buffer_create(_ff_w * _ff_h * 4, buffer_fixed, 4);
buffer_get_surface(_ff_buff, _surf, 0); buffer_get_surface(_ff_buff, _surf, 0);
var queue = ds_queue_create(); var qx = ds_queue_create();
ds_queue_enqueue(queue, [_x, _y]); var qy = ds_queue_create();
ds_queue_enqueue(qx, _x);
ds_queue_enqueue(qy, _y);
var sel_x0 = surface_w; var sel_x0 = surface_w;
var sel_y0 = surface_h; var sel_y0 = surface_h;
@ -30,10 +32,10 @@ function canvas_magic_selection_scanline(_surf, _x, _y, _thres, _corner = false)
var _arr = array_create(surface_w * surface_h, 0); var _arr = array_create(surface_w * surface_h, 0);
draw_set_color(c_white); draw_set_color(c_white);
while(!ds_queue_empty(queue)) { while(!ds_queue_empty(qx)) {
var pos = ds_queue_dequeue(queue);
x1 = pos[0]; x1 = ds_queue_dequeue(qx);
y1 = pos[1]; y1 = ds_queue_dequeue(qy);
if(_arr[y1 * surface_w + x1] == 1) continue; //Color in queue is already filled if(_arr[y1 * surface_w + x1] == 1) continue; //Color in queue is already filled
@ -60,34 +62,48 @@ function canvas_magic_selection_scanline(_surf, _x, _y, _thres, _corner = false)
//print($"> Filling {x1}, {y1}: {canvas_get_color_buffer(x1, y1)}"); //print($"> Filling {x1}, {y1}: {canvas_get_color_buffer(x1, y1)}");
if(y1 > 0) { if(y1 > 0) {
if(_corner && x1 > 0 && canvas_ms_fillable(colorBase, colorFill, x1 - 1, y1 - 1, thr)) //Check top left pixel if(_corner && x1 > 0 && canvas_ms_fillable(colorBase, colorFill, x1 - 1, y1 - 1, thr)) { //Check top left pixel
ds_queue_enqueue(queue, [x1 - 1, y1 - 1]); ds_queue_enqueue(qx, x1 - 1);
ds_queue_enqueue(qy, y1 - 1);
}
if(canvas_ms_fillable(colorBase, colorFill, x1, y1 - 1, thr)) //Check top pixel if(canvas_ms_fillable(colorBase, colorFill, x1, y1 - 1, thr)) { //Check top pixel
ds_queue_enqueue(queue, [x1, y1 - 1]); ds_queue_enqueue(qx, x1);
ds_queue_enqueue(qy, y1 - 1);
}
} }
if(y1 < surface_h - 1) { if(y1 < surface_h - 1) {
if(_corner && x1 > 0 && canvas_ms_fillable(colorBase, colorFill, x1 - 1, y1 + 1, thr)) //Check bottom left pixel if(_corner && x1 > 0 && canvas_ms_fillable(colorBase, colorFill, x1 - 1, y1 + 1, thr)) { //Check bottom left pixel
ds_queue_enqueue(queue, [x1 - 1, y1 + 1]); ds_queue_enqueue(qx, x1 - 1);
ds_queue_enqueue(qy, y1 + 1);
}
if(canvas_ms_fillable(colorBase, colorFill, x1, y1 + 1, thr)) //Check bottom pixel if(canvas_ms_fillable(colorBase, colorFill, x1, y1 + 1, thr)) { //Check bottom pixel
ds_queue_enqueue(queue, [x1, y1 + 1]); ds_queue_enqueue(qx, x1);
ds_queue_enqueue(qy, y1 + 1);
}
} }
if(_corner && x1 < surface_w - 1) { if(_corner && x1 < surface_w - 1) {
if(y1 > 0 && canvas_ms_fillable(colorBase, colorFill, x1 + 1, y1 - 1, thr)) //Check top right pixel if(y1 > 0 && canvas_ms_fillable(colorBase, colorFill, x1 + 1, y1 - 1, thr)) { //Check top right pixel
ds_queue_enqueue(queue, [x1 + 1, y1 - 1]); ds_queue_enqueue(qx, x1 + 1);
ds_queue_enqueue(qy, y1 - 1);
}
if(y1 < surface_h - 1 && canvas_ms_fillable(colorBase, colorFill, x1 + 1, y1 + 1, thr)) //Check bottom right pixel if(y1 < surface_h - 1 && canvas_ms_fillable(colorBase, colorFill, x1 + 1, y1 + 1, thr)) { //Check bottom right pixel
ds_queue_enqueue(queue, [x1 + 1, y1 + 1]); ds_queue_enqueue(qx, x1 + 1);
ds_queue_enqueue(qy, y1 + 1);
}
} }
x1++; x1++;
} }
} }
ds_queue_destroy(queue); ds_queue_destroy(qx);
ds_queue_destroy(qy);
buffer_delete(_ff_buff); buffer_delete(_ff_buff);
return [ sel_x0, sel_y0, sel_x1, sel_y1 ]; return [ sel_x0, sel_y0, sel_x1, sel_y1 ];
@ -115,7 +131,7 @@ function canvas_magic_selection_all(_surf, _x, _y, _thres) { #region
for (var j = 0; j < _ff_w; j++) { for (var j = 0; j < _ff_w; j++) {
var c = buffer_read(_ff_buff, buffer_u32); var c = buffer_read(_ff_buff, buffer_u32);
var d = color_diff(colorBase, c, true, true); var d = color_diff_alpha(colorBase, c);
if(d > _thres) continue; if(d > _thres) continue;
draw_point(j, i); draw_point(j, i);

View file

@ -21,9 +21,9 @@ function canvas_tool_fill(toolAttr) : canvas_tool() constructor {
surface_set_target(_canvas_surface); surface_set_target(_canvas_surface);
switch(_fill_type) { switch(_fill_type) {
case 0 : canvas_flood_fill_scanline(_canvas_surface, mouse_cur_x, mouse_cur_y, _thr, false); break; case 0 :
case 1 : canvas_flood_fill_scanline(_canvas_surface, mouse_cur_x, mouse_cur_y, _thr, true); break; case 1 : canvas_flood_fill_scanline(_canvas_surface, mouse_cur_x, mouse_cur_y, _thr, _fill_type); break;
case 2 : canvas_flood_fill_all( _canvas_surface, mouse_cur_x, mouse_cur_y, _thr); break; case 2 : canvas_flood_fill_all( _canvas_surface, mouse_cur_x, mouse_cur_y, _thr); break;
} }
surface_reset_target(); surface_reset_target();

View file

@ -153,19 +153,32 @@
} #endregion } #endregion
#endregion #endregion
function color_diff(c1, c2, fast = false, alpha = false) { #region function color_diff_fast(c1, c2) { #region
var _c1_r = _color_get_red(c1); INLINE
var _c1_g = _color_get_green(c1);
var _c1_b = _color_get_blue(c1);
var _c1_a = _color_get_alpha(c1);
var _c2_r = _color_get_red(c2); return (abs(_color_get_red(c1) - _color_get_red(c2)) +
var _c2_g = _color_get_green(c2); abs(_color_get_green(c1) - _color_get_green(c2)) +
var _c2_b = _color_get_blue(c2); abs(_color_get_blue(c1) - _color_get_blue(c2))
var _c2_a = _color_get_alpha(c2); ) / 3;
} #endregion
function color_diff_alpha(c1, c2) { #region
INLINE
if(fast) return (abs(_c1_r - _c2_r) + abs(_c1_g - _c2_g) + abs(_c1_b - _c2_b)) / 3; return sqrt(sqr(_color_get_red(c1) - _color_get_red(c2)) +
return sqrt(sqr(_c1_r - _c2_r) + sqr(_c1_g - _c2_g) + sqr(_c1_b - _c2_b)); sqr(_color_get_green(c1) - _color_get_green(c2)) +
sqr(_color_get_blue(c1) - _color_get_blue(c2)) +
sqr(_color_get_alpha(c1) - _color_get_alpha(c2))
);
} #endregion
function color_diff(c1, c2) { #region
INLINE
return sqrt(sqr(_color_get_red(c1) - _color_get_red(c2)) +
sqr(_color_get_green(c1) - _color_get_green(c2)) +
sqr(_color_get_blue(c1) - _color_get_blue(c2))
);
} #endregion } #endregion
#region merge #region merge

View file

@ -21,11 +21,14 @@ function Node_De_Corner(_x, _y, _group = noone) : Node_Processor(_x, _y, _group)
__init_mask_modifier(5); // inputs 7, 8, __init_mask_modifier(5); // inputs 7, 8,
inputs[| 9] = nodeValue("Include", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0b11)
.setDisplay(VALUE_DISPLAY.toggle, { data: [ "Inner", "Side" ] });
outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
input_display_list = [ 1, input_display_list = [ 1,
["Surfaces", true], 0, 5, 6, 7, 8, ["Surfaces", true], 0, 5, 6, 7, 8,
["Effect", false], 4, 2, 3, ["Effect", false], 4, 9, 2, 3,
] ]
attribute_surface_depth(); attribute_surface_depth();
@ -41,6 +44,7 @@ function Node_De_Corner(_x, _y, _group = noone) : Node_Processor(_x, _y, _group)
var _tol = _data[2]; var _tol = _data[2];
var _itr = _data[3]; var _itr = _data[3];
var _str = _data[4]; var _str = _data[4];
var _inn = _data[9];
var _sw = surface_get_width_safe(surf); var _sw = surface_get_width_safe(surf);
var _sh = surface_get_height_safe(surf); var _sh = surface_get_height_safe(surf);
@ -57,6 +61,8 @@ function Node_De_Corner(_x, _y, _group = noone) : Node_Processor(_x, _y, _group)
shader_set_f("dimension", _sw, _sh); shader_set_f("dimension", _sw, _sh);
shader_set_f("tolerance", _tol); shader_set_f("tolerance", _tol);
shader_set_i("strict", _str); shader_set_i("strict", _str);
shader_set_i("inner", bool(_inn & 0b01));
shader_set_i("side", bool(_inn & 0b10));
draw_surface_safe(temp_surface[!_bg]); draw_surface_safe(temp_surface[!_bg]);
surface_reset_shader(); surface_reset_shader();

View file

@ -1,22 +1,33 @@
//
// Simple passthrough fragment shader
//
varying vec2 v_vTexcoord; varying vec2 v_vTexcoord;
varying vec4 v_vColour; varying vec4 v_vColour;
uniform vec2 dimension; uniform vec2 dimension;
uniform float tolerance; uniform float tolerance;
uniform int strict; uniform int strict;
uniform int inner;
uniform int side;
float d(in vec4 c1, in vec4 c2) { return length(c1.rgb * c1.a - c2.rgb * c2.a) / sqrt(3.); } float d(in vec4 c1, in vec4 c2) { return length(c1.rgb * c1.a - c2.rgb * c2.a) / sqrt(3.); }
bool s(in vec4 c1, in vec4 c2) { return d(c1, c2) <= tolerance; }
vec4 a4;
bool s(in vec4 c2) { return d(a4, c2) <= tolerance; }
bool s(in bool b, in vec4 c2) { return b || d(a4, c2) <= tolerance; }
bool s(in vec4 c1, in vec4 c2) { return d(c1, c2) <= tolerance; }
bool s(in bool b, in vec4 c1, in vec4 c2) { return b || d(c1, c2) <= tolerance; }
bool ns(in vec4 c2) { return d(a4, c2) > tolerance; }
bool ns(in bool b, in vec4 c2) { return b || d(a4, c2) > tolerance; }
bool ns(in vec4 c1, in vec4 c2) { return d(c1, c2) > tolerance; }
bool ns(in bool b, in vec4 c1, in vec4 c2) { return b || d(c1, c2) > tolerance; }
float bright(in vec4 c) { return dot(c.rgb, vec3(0.2126, 0.7152, 0.0722)) * c.a; } float bright(in vec4 c) { return dot(c.rgb, vec3(0.2126, 0.7152, 0.0722)) * c.a; }
#region select closet color #region select closet color
vec4 sel2(in vec4 c, in vec4 c0, in vec4 c1) { vec4 sel2(in vec4 c0, in vec4 c1) {
float d0 = d(c, c0); float d0 = d(a4, c0);
float d1 = d(c, c1); float d1 = d(a4, c1);
float mn = min(d0, d1); float mn = min(d0, d1);
@ -24,10 +35,10 @@ float bright(in vec4 c) { return dot(c.rgb, vec3(0.2126, 0.7152, 0.0722)) * c.a;
return c1; return c1;
} }
vec4 sel3(in vec4 c, in vec4 c0, in vec4 c1, in vec4 c2) { vec4 sel3(in vec4 c0, in vec4 c1, in vec4 c2) {
float d0 = d(c, c0); float d0 = d(a4, c0);
float d1 = d(c, c1); float d1 = d(a4, c1);
float d2 = d(c, c2); float d2 = d(a4, c2);
float mn = min(min(d0, d1), d2); float mn = min(min(d0, d1), d2);
@ -36,11 +47,11 @@ float bright(in vec4 c) { return dot(c.rgb, vec3(0.2126, 0.7152, 0.0722)) * c.a;
return c2; return c2;
} }
vec4 sel4(in vec4 c, in vec4 c0, in vec4 c1, in vec4 c2, in vec4 c3) { vec4 sel4(in vec4 c0, in vec4 c1, in vec4 c2, in vec4 c3) {
float d0 = d(c, c0); float d0 = d(a4, c0);
float d1 = d(c, c1); float d1 = d(a4, c1);
float d2 = d(c, c2); float d2 = d(a4, c2);
float d3 = d(c, c3); float d3 = d(a4, c3);
float mn = min(min(d0, d1), min(d2, d3)); float mn = min(min(d0, d1), min(d2, d3));
@ -63,7 +74,7 @@ void main() {
// 3 4 5 // 3 4 5
// 6 7 8 // 6 7 8
vec4 a4 = texture2D( gm_BaseTexture, v_vTexcoord ); a4 = texture2D( gm_BaseTexture, v_vTexcoord );
vec2 tx = 1. / dimension; vec2 tx = 1. / dimension;
gl_FragColor = a4; gl_FragColor = a4;
@ -80,62 +91,65 @@ void main() {
vec4 a7 = sample( v_vTexcoord + vec2( 0., tx.y) ); vec4 a7 = sample( v_vTexcoord + vec2( 0., tx.y) );
vec4 a8 = sample( v_vTexcoord + vec2( tx.x, tx.y) ); vec4 a8 = sample( v_vTexcoord + vec2( tx.x, tx.y) );
bool n = inner == 0;
bool d = side == 0;
if(strict == 0) { if(strict == 0) {
if(s(a4, a0) && s(a4, a1) && s(a4, a3) && !s(a4, a2) && !s(a4, a5) && !s(a4, a6) && !s(a4, a7) && !s(a4, a8)) { // A A 2 if(s(n, a0) && s(a1) && s(a3) && ns(d, a2) && ns(d, a5) && ns(d, a6) && ns(d, a7) && ns(a8)) { // A A 2
// A A 5 // A A 5
// 6 7 8 // 6 7 8
gl_FragColor = sel3(a4, sel2(a4, a2, a6), sel2(a4, a5, a7), a8); gl_FragColor = n? sel3(a5, a7, a8) : sel3(sel2(a2, a6), sel2(a5, a7), a8);
return; return;
} }
if(s(a4, a1) && s(a4, a2) && s(a4, a5) && !s(a4, a0) && !s(a4, a3) && !s(a4, a6) && !s(a4, a7) && !s(a4, a8)) { // 0 A A if(s(a1) && s(n, a2) && s(a5) && ns(d, a0) && ns(d, a3) && ns(a6) && ns(d, a7) && ns(d, a8)) { // 0 A A
// 3 A A // 3 A A
// 6 7 8 // 6 7 8
gl_FragColor = sel3(a4, sel2(a4, a0, a8), sel2(a4, a3, a7), a6); gl_FragColor = n? sel3(a3, a6, a7) : sel3(sel2(a0, a8), sel2(a3, a7), a6);
return; return;
} }
if(s(a4, a3) && s(a4, a6) && s(a4, a7) && !s(a4, a0) && !s(a4, a1) && !s(a4, a2) && !s(a4, a5) && !s(a4, a8)) { // 0 1 2 if(s(a3) && s(n, a6) && s(a7) && ns(d, a0) && ns(d, a1) && ns(a2) && ns(d, a5) && ns(d, a8)) { // 0 1 2
// A A 5 // A A 5
// A A 8 // A A 8
gl_FragColor = sel3(a4, sel2(a4, a0, a8), sel2(a4, a1, a5), a2); gl_FragColor = n? sel3(a1, a2, a5) : sel3(sel2(a0, a8), sel2(a1, a5), a2);
return; return;
} }
if(s(a4, a5) && s(a4, a7) && s(a4, a8) && !s(a4, a0) && !s(a4, a1) && !s(a4, a2) && !s(a4, a3) && !s(a4, a6)) { // 0 1 2 if(s(a5) && s(a7) && s(n, a8) && ns(a0) && ns(d, a1) && ns(d, a2) && ns(d, a3) && ns(d, a6)) { // 0 1 2
// 3 A A // 3 A A
// 6 A A // 6 A A
gl_FragColor = sel3(a4, sel2(a4, a2, a6), sel2(a4, a1, a3), a0); gl_FragColor = n? sel3(a0, a1, a3) : sel3(sel2(a2, a6), sel2(a1, a3), a0);
return; return;
} }
} else if(strict == 1) { } else if(strict == 1) {
if(s(a5, a7) && s(a4, a1) && s(a4, a3) && s(a4, a0) && !s(a4, a2) && !s(a4, a5) && !s(a4, a6) && !s(a4, a7)) { // B B C if(s(a5, a7) && s(a1) && s(a3) && s(n, a0) && ns(d, a2) && ns(d, a5) && ns(d, a6) && ns(d, a7)) { // B B C
// B B A // B B A
// C A 8 // C A 8
gl_FragColor = sel3(a4, sel2(a4, a2, a6), sel2(a4, a5, a7), a8); gl_FragColor = n? sel3(a5, a7, a8) : sel3(sel2(a2, a6), sel2(a5, a7), a8);
return; return;
} }
if(s(a3, a7) && s(a4, a1) && s(a4, a2) && s(a4, a5) && !s(a4, a0) && !s(a4, a3) && !s(a4, a7) && !s(a4, a8)) { // C B B if(s(a3, a7) && s(a1) && s(n, a2) && s(a5) && ns(d, a0) && ns(d, a3) && ns(d, a7) && ns(d, a8)) { // C B B
// A B B // A B B
// 6 A C // 6 A C
gl_FragColor = sel3(a4, sel2(a4, a0, a8), sel2(a4, a3, a7), a6); gl_FragColor = n? sel3(a3, a6, a7) : sel3(sel2(a0, a8), sel2(a3, a7), a6);
return; return;
} }
if(s(a5, a1) && s(a4, a3) && s(a4, a6) && s(a4, a7) && !s(a4, a0) && !s(a4, a1) && !s(a4, a5) && !s(a4, a8)) { // C A 2 if(s(a5, a1) && s(a3) && s(n, a6) && s(a7) && ns(d, a0) && ns(d, a1) && ns(d, a5) && ns(d, a8)) { // C A 2
// B B A // B B A
// B B C // B B C
gl_FragColor = sel3(a4, sel2(a4, a0, a8), sel2(a4, a1, a5), a2); gl_FragColor = n? sel3(a1, a2, a5) : sel3(sel2(a0, a8), sel2(a1, a5), a2);
return; return;
} }
if(s(a3, a1) && s(a4, a5) && s(a4, a8) && s(a4, a7) && !s(a4, a2) && !s(a4, a1) && !s(a4, a3) && !s(a4, a6)) { // 0 A C if(s(a3, a1) && s(a5) && s(n, a8) && s(a7) && ns(d, a2) && ns(d, a1) && ns(d, a3) && ns(d, a6)) { // 0 A C
// A B B // A B B
// C B B // C B B
gl_FragColor = sel3(a4, sel2(a4, a2, a6), sel2(a4, a1, a3), a0); gl_FragColor = n? sel3(a0, a1, a3) : sel3(sel2(a2, a6), sel2(a1, a3), a0);
return; return;
} }
} }