smear invert

This commit is contained in:
Tanasart 2024-07-09 18:24:20 +07:00
parent 118e23700a
commit 4a5cf38ce0
7 changed files with 270 additions and 43 deletions

Binary file not shown.

View file

@ -2,9 +2,10 @@ enum CANVAS_TOOL_SHAPE_ISO {
cube, cube,
} }
function canvas_tool_shape_iso(brush, shape) : canvas_tool() constructor { function canvas_tool_shape_iso(brush, shape, toolAttr) : canvas_tool() constructor {
self.brush = brush; self.brush = brush;
self.shape = shape; self.shape = shape;
self.tool_attribute = toolAttr;
use_color_3d = true; use_color_3d = true;
brush_resizable = true; brush_resizable = true;
@ -23,9 +24,14 @@ function canvas_tool_shape_iso(brush, shape) : canvas_tool() constructor {
mouse_cur_x = round((_mx - _x) / _s - 0.5); mouse_cur_x = round((_mx - _x) / _s - 0.5);
mouse_cur_y = round((_my - _y) / _s - 0.5); mouse_cur_y = round((_my - _y) / _s - 0.5);
var _ang = tool_attribute.iso_angle;
if(mouse_holding) { if(mouse_holding) {
surface_set_shader(drawing_surface, noone); surface_set_shader(drawing_surface, noone);
canvas_draw_iso_cube(brush, mouse_points, subtool);
if(_ang == 0) canvas_draw_iso_cube( brush, mouse_points, subtool);
else if(_ang == 1) canvas_draw_diag_cube(brush, mouse_points, subtool);
surface_reset_shader(); surface_reset_shader();
} }
@ -201,6 +207,189 @@ function canvas_draw_iso_cube(brush, _p, _fill = false) {
draw_set_color(cc); draw_set_color(cc);
if(_fill == 2) {
if(d == 0) {
canvas_draw_line(p0x, p0y, p0px - 1, p0py);
canvas_draw_line(p0px, p0py, p1x, p1y);
canvas_draw_line(p1x, p1y, p1px + 1, p1py);
canvas_draw_line(p1px, p1py, p0x, p0y);
canvas_draw_triangle(p0x, p0y, p0px - 1, p0py, p1x - 1, p1y, false);
canvas_draw_triangle(p1x - 1, p1y, p1px, p1py - 1, p0x, p0y, false);
} else {
draw_set_color(brush.colors[1]);
canvas_draw_triangle(p0px, p0py - 1, p1x, p1y + d, p1x, p1y, false);
canvas_draw_triangle(p0px, p0py - 1, p1x, p1y + d, p0px, p0py + d, false);
canvas_draw_line(p0px, p0py + 1 + d, p1x, p1y + 1 + d);
canvas_draw_line(p0px, p0py, p1x, p1y);
canvas_draw_line(p0px, p0py - 1, p0px, p0py + d);
if(d < -1) canvas_draw_line(p0px, p0py - 1, p1x, p1y - 1);
draw_set_color(brush.colors[0]);
canvas_draw_triangle(p0px - 1, p0py, p0x, p0y + d, p0x, p0y, false);
canvas_draw_triangle(p0px - 1, p0py, p0x, p0y + d, p0px - 1, p0py - 1 + d, false);
canvas_draw_line(p0x, p0y + d, p0px - 1, p0py + d);
canvas_draw_line(p0x, p0y, p0px - 1, p0py);
canvas_draw_line(p0x, p0y, p0x, p0y + d);
canvas_draw_line(p0px - 1, p0py, p0px - 1, p0py + d);
draw_set_color(cc);
canvas_draw_triangle(p0x, p0y + d, p0px - 1, p0py + d, p1x - 1, p1y + d, false);
canvas_draw_triangle(p1x - 1, p1y + d, p1px, p1py + d - 1, p0x, p0y + d, false);
canvas_draw_line(p0x, p0y + d, p0px - 1, p0py + d);
canvas_draw_line(p0px, p0py + d, p1x, p1y + d);
canvas_draw_line(p1x, p1y + d, p1px + 1, p1py + d);
canvas_draw_line(p1px, p1py + d, p0x, p0y + d);
}
} else {
canvas_draw_line_brush(brush, p0x, p0y, p0px - 1, p0py);
canvas_draw_line_brush(brush, p0px, p0py, p1x, p1y);
if(_fill == 1) {
canvas_draw_line_brush(brush, p1x, p1y, p1px + 1, p1py);
canvas_draw_line_brush(brush, p1px, p1py, p0x, p0y);
}
if(d != 0) {
canvas_draw_line_brush(brush, p0x, p0y + d, p0px - 1, p0py + d);
canvas_draw_line_brush(brush, p0px, p0py + d, p1x, p1y + d);
canvas_draw_line_brush(brush, p1x, p1y + d, p1px + 1, p1py + d);
canvas_draw_line_brush(brush, p1px, p1py + d, p0x, p0y + d);
canvas_draw_line_brush(brush, p0x, p0y, p0x, p0y + d);
canvas_draw_line_brush(brush, p1x, p1y, p1x, p1y + d);
canvas_draw_line_brush(brush, p0px - 1, p0py, p0px - 1, p0py + d);
if(_fill == 1)
canvas_draw_line_brush(brush, p1px, p1py, p1px, p1py + d);
} else if(_fill == 0) {
canvas_draw_line_brush(brush, p1x, p1y, p1px + 1, p1py);
canvas_draw_line_brush(brush, p1px, p1py, p0x, p0y);
}
}
}
}
function canvas_draw_diag_cube(brush, _p, _fill = false) {
var p0x = _p[0][0], p0y = _p[0][1];
var p1x = _p[1][0], p1y = _p[1][1];
var ww = p1x - p0x;
var cc = draw_get_color();
if(p1x < p0x) {
var tx = p0x, ty = p0y;
p0x = p1x; p0y = p1y;
p1x = tx; p1y = ty;
}
if(p1x == p0x && p1y > p0y) {
var t = p0y;
p0y = p1y;
p1y = t;
}
if(p1x == p0x && p1y < p0y) p1x++;
var d = _p[2];
var w = p1x - p0x + 1;
var h = p0y - p1y;
var h1 = (w - h) / 2;
var h2 = h1 + h;
var w1 = h1;
var p0px = p0x + w1;
var p0py = p0y + h1;
var p1px = p1x - w1;
var p1py = p1y - h1;
var _simp = true;
if(w > 0) {
if(round(h2) < 0) {
if(round(w1) > 0) {
p0x = floor(p1px);
p0y = floor(p1py);
p1x = ceil(p0px) + 1;
p1y = ceil(p0py);
if(ww < 0) { p0x--; p1x--; }
_simp = false;
}
} else if(round(h2) > 0) {
if(round(w1) < 0) {
p0x = floor(p0px);
p0y = floor(p0py);
p1x = ceil(p1px) + 1;
p1y = ceil(p1py);
if(frac(p0py) >= 0.5) { p0x--; }
if(ww < 0 && frac(p0px) == 0 && frac(p0py) == 0) { p0x--; p1x--; }
_simp = false;
} else if(round(w1) > 0) {
_simp = false;
}
}
}
if(_simp) {
if(_fill == 2) {
if(d == 0) {
canvas_draw_line(p0x, p0y, p1x, p1y);
} else {
canvas_draw_triangle(p0x, p0y, p1x, p1y, p1x, p1y + d, false);
canvas_draw_triangle(p0x, p0y, p0x, p0y + d, p1x, p1y + d, false);
}
} else {
canvas_draw_line_brush(brush, p0x, p0y, p1x, p1y);
if(d != 0) {
canvas_draw_line_brush(brush, p0x, p0y + d, p1x, p1y + d);
canvas_draw_line_brush(brush, p0x, p0y, p0x, p0y + d);
canvas_draw_line_brush(brush, p1x, p1y, p1x, p1y + d);
}
}
} else {
var w = p1x - p0x + 1;
var h = p0y - p1y;
var h1 = (w - h) / 2;
var h2 = h1 + h;
var w1 = h1;
var p0px = p0x + w1;
var p0py = p0y + h1;
var p1px = p1x - w1;
var p1py = p1y - h1;
p0py -= (abs(w) > 4);
p1py += (abs(w) > 4);
if(d > 0) {
p0y += d;
p1y += d;
p0py += d;
p1py += d;
d = -d;
}
draw_set_color(cc);
if(_fill == 2) { if(_fill == 2) {
if(d == 0) { if(d == 0) {
canvas_draw_line(p0x, p0y, p0px - 1, p0py); canvas_draw_line(p0x, p0y, p0px - 1, p0py);

View file

@ -38,7 +38,7 @@
LATEST_VERSION = 11700; LATEST_VERSION = 11700;
VERSION = 11761; VERSION = 11761;
SAVE_VERSION = 11700; SAVE_VERSION = 11700;
VERSION_STRING = "1.17.7.003"; VERSION_STRING = "1.17.7.004";
BUILD_NUMBER = 11761; BUILD_NUMBER = 11761;
globalvar HOTKEYS, HOTKEY_CONTEXT; globalvar HOTKEYS, HOTKEY_CONTEXT;

View file

@ -216,7 +216,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
tool_eraser = new canvas_tool_brush(brush, true); tool_eraser = new canvas_tool_brush(brush, true);
tool_rectangle = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.rectangle); tool_rectangle = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.rectangle);
tool_ellipse = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.ellipse); tool_ellipse = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.ellipse);
tool_iso_cube = new canvas_tool_shape_iso(brush, CANVAS_TOOL_SHAPE_ISO.cube); tool_iso_cube = new canvas_tool_shape_iso(brush, CANVAS_TOOL_SHAPE_ISO.cube, tool_attribute);
tool_fill = new canvas_tool_fill(tool_attribute); tool_fill = new canvas_tool_fill(tool_attribute);
tool_freeform = new canvas_tool_draw_freeform(brush); tool_freeform = new canvas_tool_draw_freeform(brush);
@ -272,18 +272,22 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
tool_fil8 = [ "Fill", tool_fil8_edit, "fillType", tool_attribute ]; tool_fil8 = [ "Fill", tool_fil8_edit, "fillType", tool_attribute ];
tool_attribute.button_apply = [ false, false ]; tool_attribute.button_apply = [ false, false ];
tool_curve_apply = button( function() { tool_curve_bez.apply(); } ).setIcon(THEME.toolbar_check, 0); tool_curve_apply = button( function() { tool_curve_bez.apply(); } ).setIcon(THEME.toolbar_check, 0);
tool_curve_cancel = button( function() { tool_curve_bez.cancel(); } ).setIcon(THEME.toolbar_check, 1); tool_curve_cancel = button( function() { tool_curve_bez.cancel(); } ).setIcon(THEME.toolbar_check, 1);
toolObject_selection_magic = new NodeTool( "Magic Selection", THEME.canvas_tools_magic_selection ) tool_attribute.iso_angle = 0;
.setSetting(tool_thrs, tool_fil8) tool_isoangle = new buttonGroup( [ THEME.canvas_iso_angle, THEME.canvas_iso_angle ], function(val) { tool_attribute.iso_angle = val; })
.setToolObject(tool_sel_magic) .setTooltips( [ "2:1", "1:1" ] )
.setCollape(false);
tool_iso_settings = [ "", tool_isoangle, "iso_angle", tool_attribute ];
tools = [ tools = [
new NodeTool( "Selection", [ THEME.canvas_tools_selection_rectangle, THEME.canvas_tools_selection_circle, THEME.canvas_tools_freeform_selection, THEME.canvas_tools_selection_brush ]) new NodeTool( "Selection", [ THEME.canvas_tools_selection_rectangle, THEME.canvas_tools_selection_circle, THEME.canvas_tools_freeform_selection, THEME.canvas_tools_selection_brush ])
.setToolObject([ tool_sel_rectangle, tool_sel_ellipse, tool_sel_freeform, tool_sel_brush ]), .setToolObject([ tool_sel_rectangle, tool_sel_ellipse, tool_sel_freeform, tool_sel_brush ]),
toolObject_selection_magic, new NodeTool( "Magic Selection", THEME.canvas_tools_magic_selection )
.setSetting(tool_thrs, tool_fil8)
.setToolObject(tool_sel_magic),
new NodeTool( "Pencil", THEME.canvas_tools_pencil) new NodeTool( "Pencil", THEME.canvas_tools_pencil)
.setSetting(tool_size) .setSetting(tool_size)
@ -302,7 +306,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
.setToolObject(tool_ellipse), .setToolObject(tool_ellipse),
new NodeTool( "Iso Cube", [ THEME.canvas_tools_iso_cube, THEME.canvas_tools_iso_cube_wire, THEME.canvas_tools_iso_cube_fill ]) new NodeTool( "Iso Cube", [ THEME.canvas_tools_iso_cube, THEME.canvas_tools_iso_cube_wire, THEME.canvas_tools_iso_cube_fill ])
.setSetting(tool_size) .setSetting(tool_size, tool_iso_settings)
.setToolObject(tool_iso_cube), .setToolObject(tool_iso_cube),
new NodeTool( "Curve", THEME.canvas_tool_curve_icon) new NodeTool( "Curve", THEME.canvas_tool_curve_icon)

View file

@ -667,7 +667,7 @@ function __initNodes() {
addNodeObject(d3d, "3D Repeat", s_node_3d_array, "Node_3D_Repeat", [1, Node_3D_Repeat],, "Repeat the same 3D mesh multiple times.").setVersion(11510); addNodeObject(d3d, "3D Repeat", s_node_3d_array, "Node_3D_Repeat", [1, Node_3D_Repeat],, "Repeat the same 3D mesh multiple times.").setVersion(11510);
addNodeObject(d3d, "Transform 3D", s_node_image_transform_3d, "Node_3D_Transform_Image", [1, Node_3D_Transform_Image],, "Transform image in 3D space").setVersion(11600); addNodeObject(d3d, "Transform 3D", s_node_image_transform_3d, "Node_3D_Transform_Image", [1, Node_3D_Transform_Image],, "Transform image in 3D space").setVersion(11600);
addNodeObject(d3d, "Mesh Export", s_node_3d_obj_export, "Node_3D_Mesh_Export", [1, Node_3D_Mesh_Export],, "Export 3D mesh as .obj file").setVersion(11740); addNodeObject(d3d, "Mesh Export", s_node_3d_obj_export, "Node_3D_Mesh_Export", [1, Node_3D_Mesh_Export],, "Export 3D mesh as .obj file").setVersion(11740);
ds_list_add(d3d, "Mesh"); ds_list_add(d3d, "Mesh");
addNodeObject(d3d, "3D Object", s_node_3d_obj, "Node_3D_Mesh_Obj", [0, Node_create_3D_Obj],, "Load .obj file from your computer as a 3D object.").setVersion(11510); addNodeObject(d3d, "3D Object", s_node_3d_obj, "Node_3D_Mesh_Obj", [0, Node_create_3D_Obj],, "Load .obj file from your computer as a 3D object.").setVersion(11510);
addNodeObject(d3d, "3D Plane", s_node_3d_plane, "Node_3D_Mesh_Plane", [1, Node_3D_Mesh_Plane],, "Put 2D image on a plane in 3D space.").setVersion(11510); addNodeObject(d3d, "3D Plane", s_node_3d_plane, "Node_3D_Mesh_Plane", [1, Node_3D_Mesh_Plane],, "Put 2D image on a plane in 3D space.").setVersion(11510);

View file

@ -41,9 +41,11 @@ function Node_Smear(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con
inputs[| 13] = nodeValue("Spread", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) inputs[| 13] = nodeValue("Spread", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0)
.setDisplay(VALUE_DISPLAY.slider, { range : [ 0, 30, 1 ] }); .setDisplay(VALUE_DISPLAY.slider, { range : [ 0, 30, 1 ] });
inputs[| 14] = nodeValue("Invert", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false);
input_display_list = [ 5, 6, input_display_list = [ 5, 6,
["Surfaces", true], 0, 3, 4, 7, 8, ["Surfaces", true], 0, 3, 4, 7, 8,
["Smear", false], 11, 1, 9, 2, 10, 13, 12, ["Smear", false], 11, 14, 1, 9, 2, 10, 13, 12,
] ]
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);
@ -51,7 +53,7 @@ function Node_Smear(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con
attribute_surface_depth(); attribute_surface_depth();
attribute_oversample(); attribute_oversample();
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
var _surf = outputs[| 0].getValue(); var _surf = outputs[| 0].getValue();
if(is_array(_surf)) { if(is_array(_surf)) {
if(array_length(_surf) == 0) return; if(array_length(_surf) == 0) return;
@ -64,23 +66,28 @@ function Node_Smear(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con
var hv = inputs[| 2].drawOverlay(hover, active, _x + ww / 2 * _s, _y + hh / 2 * _s, _s, _mx, _my, _snx, _sny); _hov |= hv; var hv = inputs[| 2].drawOverlay(hover, active, _x + ww / 2 * _s, _y + hh / 2 * _s, _s, _mx, _my, _snx, _sny); _hov |= hv;
return _hov; return _hov;
} #endregion }
static step = function() { #region static step = function() {
__step_mask_modifier(); __step_mask_modifier();
inputs[| 1].mappableStep(); inputs[| 1].mappableStep();
inputs[| 2].mappableStep(); inputs[| 2].mappableStep();
} #endregion }
static processData = function(_outSurf, _data, _output_index, _array_index) { #region static processData = function(_outSurf, _data, _output_index, _array_index) {
var _dim = surface_get_dimension(_data[0]);
surface_set_shader(_outSurf, sh_smear); surface_set_shader(_outSurf, sh_smear);
shader_set_f("size", max(surface_get_width_safe(_data[0]), surface_get_height_safe( _data[0]))); shader_set_f("dimension", _dim);
shader_set_f("size", max(_dim[0], _dim[1]));
shader_set_f_map("strength", _data[ 1], _data[ 9], inputs[| 1]); shader_set_f_map("strength", _data[ 1], _data[ 9], inputs[| 1]);
shader_set_f_map("direction", _data[ 2], _data[10], inputs[| 2]); shader_set_f_map("direction", _data[ 2], _data[10], inputs[| 2]);
shader_set_i("sampleMode", struct_try_get(attributes, "oversample")); shader_set_i("sampleMode", struct_try_get(attributes, "oversample"));
shader_set_i("alpha", _data[11]); shader_set_i("alpha", _data[11]);
shader_set_i("inv", _data[14]);
shader_set_i("modulateStr", _data[12]); shader_set_i("modulateStr", _data[12]);
shader_set_f("spread", _data[13]); shader_set_f("spread", _data[13]);
@ -92,5 +99,5 @@ function Node_Smear(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con
_outSurf = channel_apply(_data[0], _outSurf, _data[6]); _outSurf = channel_apply(_data[0], _outSurf, _data[6]);
return _outSurf; return _outSurf;
} #endregion }
} }

View file

@ -12,9 +12,11 @@ uniform vec2 strength;
uniform int strengthUseSurf; uniform int strengthUseSurf;
uniform sampler2D strengthSurf; uniform sampler2D strengthSurf;
uniform int sampleMode; uniform vec2 dimension;
uniform int alpha; uniform int sampleMode;
uniform int modulateStr; uniform int alpha;
uniform int modulateStr;
uniform int inv;
vec4 sampleTexture(vec2 pos) { #region vec4 sampleTexture(vec2 pos) { #region
if(pos.x >= 0. && pos.y >= 0. && pos.x <= 1. && pos.y <= 1.) if(pos.x >= 0. && pos.y >= 0. && pos.x <= 1. && pos.y <= 1.)
@ -35,36 +37,61 @@ vec4 sampleTexture(vec2 pos) { #region
return vec4(0.); return vec4(0.);
} #endregion } #endregion
vec4 smear(vec2 angle) { #region vec4 smear(vec2 shift) {
float delta = 1. / size; float delta = 1. / size;
vec4 base = sampleTexture( v_vTexcoord ); vec4 base = sampleTexture( v_vTexcoord );
float maxBright = (base.r + base.g + base.b) / 3. * base.a; float mBri = (base.r + base.g + base.b) / 3. * base.a;
vec4 res = base; vec4 res = base;
vec4 col, rcol;
float bright, rbright, dist = 0.;
for(float i = 0.; i <= 1.0; i += delta) { if(inv == 0) {
vec4 col = sampleTexture( v_vTexcoord - angle * i); for(float i = 0.; i <= 1.0; i += delta) {
col = sampleTexture( v_vTexcoord - shift * i);
if(modulateStr != 2) {
if(alpha == 0) col.rgb *= 1. - i; if(modulateStr != 2) {
else col.a *= 1. - i; if(alpha == 0) col.rgb *= 1. - i;
else col.a *= 1. - i;
}
bright = (col.r + col.g + col.b) / 3. * col.a;
if(bright > mBri) {
mBri = bright;
res = col;
}
} }
float bright = (col.r + col.g + col.b) / 3. * col.a;
if(bright > maxBright) { if(modulateStr == 1) {
maxBright = bright; if(alpha == 0) res.rgb *= mBri;
res = col; else res.a *= res.a;
}
} else if(inv == 1) {
base = alpha == 0? vec4(0., 0., 0., 1.) : vec4(0.);
mBri = 0.;
res = base;
for(float i = 0.; i <= 1.; i += delta) {
col = sampleTexture( v_vTexcoord + shift * i);
bright = (col.r + col.g + col.b) / 3. * col.a;
if(bright == 0.) continue;
if(i > bright) continue;
if(modulateStr != 2) {
if(alpha == 0) col.rgb *= i;
else col.a *= i;
}
mBri = bright;
res = alpha == 0? vec4(vec3(i), 1.) : vec4(vec3(1.), i);
} }
}
if(modulateStr == 1) {
if(alpha == 0) res.rgb *= maxBright;
else res.a *= res.a;
} }
return res; return res;
} #endregion }
void main() { void main() {
float str = strength.x; float str = strength.x;