From 31a4e7e658a7095b27f15b6ce2a1d5a1daa36602 Mon Sep 17 00:00:00 2001 From: Tanasart Date: Sat, 5 Oct 2024 15:30:21 +0700 Subject: [PATCH] [Convolute] Add normalize option, custom kernel size. --- scripts/matrixGrid/matrixGrid.gml | 60 +++++++------------ scripts/nodeValue_drawer/nodeValue_drawer.gml | 5 ++ scripts/node_convolution/node_convolution.gml | 23 +++++-- scripts/textBox/textBox.gml | 12 ++-- scripts/textInput/textInput.gml | 11 ++-- shaders/sh_convolution/sh_convolution.fsh | 41 ++++++++----- 6 files changed, 84 insertions(+), 68 deletions(-) diff --git a/scripts/matrixGrid/matrixGrid.gml b/scripts/matrixGrid/matrixGrid.gml index 40489911d..6a8688de5 100644 --- a/scripts/matrixGrid/matrixGrid.gml +++ b/scripts/matrixGrid/matrixGrid.gml @@ -1,19 +1,18 @@ function matrixGrid(_type, _size, _onModify, _unit = noone) : widget() constructor { type = _type; - size = _size; - inputs = size * size; + size = 1; onModify = _onModify; unit = _unit; linked = false; - b_link = button(function() { linked = !linked; }); + b_link = button(function() /*=>*/ { linked = !linked; }); b_link.icon = THEME.value_link; onModifyIndex = function(val, index) { var modi = false; if(linked) { - for( var i = 0; i < inputs; i++ ) + for( var i = 0; i < size * size; i++ ) modi |= onModify(toNumber(val), i); return modi; } @@ -21,38 +20,26 @@ function matrixGrid(_type, _size, _onModify, _unit = noone) : widget() construct return onModify(toNumber(val), index); } - onModifySingle[0] = function(val) { return onModifyIndex(val, 0); } - onModifySingle[1] = function(val) { return onModifyIndex(val, 1); } - onModifySingle[2] = function(val) { return onModifyIndex(val, 2); } - onModifySingle[3] = function(val) { return onModifyIndex(val, 3); } - - onModifySingle[4] = function(val) { return onModifyIndex(val, 4); } - onModifySingle[5] = function(val) { return onModifyIndex(val, 5); } - onModifySingle[6] = function(val) { return onModifyIndex(val, 6); } - onModifySingle[7] = function(val) { return onModifyIndex(val, 7); } - - onModifySingle[ 8] = function(val) { return onModifyIndex(val, 8); } - onModifySingle[ 9] = function(val) { return onModifyIndex(val, 9); } - onModifySingle[10] = function(val) { return onModifyIndex(val, 10); } - onModifySingle[11] = function(val) { return onModifyIndex(val, 11); } - - onModifySingle[12] = function(val) { return onModifyIndex(val, 12); } - onModifySingle[13] = function(val) { return onModifyIndex(val, 13); } - onModifySingle[14] = function(val) { return onModifyIndex(val, 14); } - onModifySingle[15] = function(val) { return onModifyIndex(val, 15); } - extras = -1; - for(var i = 0; i < inputs; i++) { - tb[i] = new textBox(_type, onModifySingle[i]); - tb[i].slidable = true; - } + static setSize = function(_size) { + if(size == _size) return self; + size = _size; + + for(var i = 0; i < size * size; i++) { + tb[i] = new textBox(type, onModifyIndex); + tb[i].onModifyParam = i; + tb[i].slidable = true; + } + + return self; + } setSize(_size); - static setInteract = function(interactable = noone) { - self.interactable = interactable; + static setInteract = function(interactable = false) { + self.interactable = interactable; b_link.interactable = interactable; - for( var i = 0; i < inputs; i++ ) + for( var i = 0; i < size * size; i++ ) tb[i].interactable = interactable; if(extras) @@ -62,7 +49,7 @@ function matrixGrid(_type, _size, _onModify, _unit = noone) : widget() construct static register = function(parent = noone) { b_link.register(parent); - for( var i = 0; i < inputs; i++ ) + for( var i = 0; i < size * size; i++ ) tb[i].register(parent); if(extras) @@ -73,13 +60,13 @@ function matrixGrid(_type, _size, _onModify, _unit = noone) : widget() construct } static isHovering = function() { - for( var i = 0, n = array_length(tb); i < n; i++ ) if(tb[i].isHovering()) return true; + for( var i = 0, n = size * size; i < n; i++ ) if(tb[i].isHovering()) return true; return false; } static drawParam = function(params) { setParam(params); - for(var i = 0; i < inputs; i++) + for(var i = 0; i < size * size; i++) tb[i].setParam(params); return draw(params.x, params.y, params.w, params.h, params.data, params.m); @@ -91,6 +78,8 @@ function matrixGrid(_type, _size, _onModify, _unit = noone) : widget() construct w = _w; h = _h * size; + var ww = _w / size; + var _bs = min(_h, ui(32)); if((_w - _bs) / size > ui(64)) { if(extras && instanceof(extras) == "buttonClass") { @@ -122,8 +111,6 @@ function matrixGrid(_type, _size, _onModify, _unit = noone) : widget() construct } - var ww = _w / size; - draw_sprite_stretched_ext(THEME.textbox, 3, _x, _y, ww * size, _h * size, boxColor, 1); draw_sprite_stretched_ext(THEME.textbox, 0, _x, _y, ww * size, _h * size, boxColor, 0.5 + 0.5 * interactable); @@ -147,7 +134,6 @@ function matrixGrid(_type, _size, _onModify, _unit = noone) : widget() construct static clone = function() { var cln = new matrixGrid(type, size, onModify, unit); - return cln; } } \ No newline at end of file diff --git a/scripts/nodeValue_drawer/nodeValue_drawer.gml b/scripts/nodeValue_drawer/nodeValue_drawer.gml index 9e02cf724..c9596da54 100644 --- a/scripts/nodeValue_drawer/nodeValue_drawer.gml +++ b/scripts/nodeValue_drawer/nodeValue_drawer.gml @@ -31,6 +31,11 @@ function drawWidget(xx, yy, ww, _m, jun, global_var = true, _hover = false, _foc case "controlPointBox" : case "transformBox" : breakLine = true; + break; + + case "matrixGrid" : + breakLine = wid.size > 5; + break; } var butx = xx; diff --git a/scripts/node_convolution/node_convolution.gml b/scripts/node_convolution/node_convolution.gml index 9f12699f9..7b1970210 100644 --- a/scripts/node_convolution/node_convolution.gml +++ b/scripts/node_convolution/node_convolution.gml @@ -21,28 +21,39 @@ function Node_Convolution(_x, _y, _group = noone) : Node_Processor(_x, _y, _grou __init_mask_modifier(3); // inputs 7, 8, + newInput(9, nodeValue_Bool("Normalize", self, false)); + + newInput(10, nodeValue_Int("Size", self, 3)) + newOutput(0, nodeValue_Output("Surface out", self, VALUE_TYPE.surface, noone)); input_display_list = [ 5, 6, ["Surfaces", true], 0, 3, 4, 7, 8, - ["Kernel", false], 1, + ["Kernel", false], 10, 1, 9, ]; attribute_surface_depth(); attribute_oversample(); - static step = function() { #region + static step = function() { __step_mask_modifier(); - } #endregion + } static processData = function(_outSurf, _data, _output_index, _array_index) { var _ker = _data[1]; + var _nrm = _data[9]; + var _siz = max(3, _data[10]); var _sam = struct_try_get(attributes, "oversample"); + inputs[1].editWidget.setSize(_siz); + _ker = array_verify(_ker, _siz * _siz); + surface_set_shader(_outSurf, sh_convolution); - shader_set_f("dimension", surface_get_width_safe(_outSurf), surface_get_height_safe(_outSurf)); - shader_set_f("kernel", _ker); - shader_set_i("sampleMode", _sam); + shader_set_dim("dimension", _outSurf); + shader_set_f("kernel", _ker); + shader_set_i("size", _siz); + shader_set_i("sampleMode", _sam); + shader_set_i("normalized", _nrm); draw_surface_safe(_data[0]); surface_reset_shader(); diff --git a/scripts/textBox/textBox.gml b/scripts/textBox/textBox.gml index 18d7f6f15..b812e40ed 100644 --- a/scripts/textBox/textBox.gml +++ b/scripts/textBox/textBox.gml @@ -82,7 +82,8 @@ function textBox(_input, _onModify) : textInput(_input, _onModify) constructor { if(use_range) value = clamp(value, range_min, range_max); } - onModify(value); + if(onModifyParam == noone) onModify(value); + else onModify(value, onModifyParam); } static setSlideType = function(_slide_int = false) { slide_int = _slide_int; return self; } @@ -177,7 +178,8 @@ function textBox(_input, _onModify) : textInput(_input, _onModify) constructor { } } else { if(is_callable(onModify)) { - var _modi = onModify(_val); + var _modi = onModifyParam == noone? onModify(_val) : onModify(_val, onModifyParam); + if(_modi && IS_PATREON) shake_amount = PREFERENCES.textbox_shake / 4; return _modi; } @@ -813,8 +815,10 @@ function textBox(_input, _onModify) : textInput(_input, _onModify) constructor { if(DRAGGING && (DRAGGING.type == "Text" || DRAGGING.type == "Number") && hover && hoverRect) { draw_sprite_stretched_ext(THEME.ui_panel, 1, _x, _y, _w, _h, COLORS._main_value_positive, 1); - if(mouse_release(mb_left)) - onModify(DRAGGING.data); + if(mouse_release(mb_left)) { + if(onModifyParam == noone) onModify(DRAGGING.data); + else onModify(DRAGGING.data, onModifyParam); + } } selecting = self == WIDGET_CURRENT; diff --git a/scripts/textInput/textInput.gml b/scripts/textInput/textInput.gml index f86c9c540..fc82ab05a 100644 --- a/scripts/textInput/textInput.gml +++ b/scripts/textInput/textInput.gml @@ -1,10 +1,11 @@ function textInput(_input, _onModify) : widget() constructor { - input = _input; - onModify = _onModify; - selecting = false; - auto_update = false; + input = _input; + onModify = _onModify; + onModifyParam = noone; + selecting = false; + auto_update = false; - typing = false; + typing = false; parser_server = noone; diff --git a/shaders/sh_convolution/sh_convolution.fsh b/shaders/sh_convolution/sh_convolution.fsh index db3819989..63636d63f 100644 --- a/shaders/sh_convolution/sh_convolution.fsh +++ b/shaders/sh_convolution/sh_convolution.fsh @@ -4,9 +4,11 @@ varying vec2 v_vTexcoord; varying vec4 v_vColour; -uniform vec2 dimension; -uniform float kernel[9]; -uniform int sampleMode; +uniform int size; +uniform vec2 dimension; +uniform float kernel[256]; +uniform int sampleMode; +uniform int normalized; vec4 sampleTexture(vec2 pos) { if(pos.x >= 0. && pos.y >= 0. && pos.x <= 1. && pos.y <= 1.) @@ -28,18 +30,25 @@ vec4 sampleTexture(vec2 pos) { } void main() { - vec2 tex = 1. / dimension; - vec4 c = + kernel[0] * sampleTexture( v_vTexcoord + vec2(-tex.x, -tex.y) ) - + kernel[1] * sampleTexture( v_vTexcoord + vec2( 0., -tex.y) ) - + kernel[2] * sampleTexture( v_vTexcoord + vec2( tex.x, -tex.y) ) - - + kernel[3] * sampleTexture( v_vTexcoord + vec2(-tex.x, 0.) ) - + kernel[4] * sampleTexture( v_vTexcoord + vec2( 0., 0.) ) - + kernel[5] * sampleTexture( v_vTexcoord + vec2( tex.x, 0.) ) - - + kernel[6] * sampleTexture( v_vTexcoord + vec2(-tex.x, tex.y) ) - + kernel[7] * sampleTexture( v_vTexcoord + vec2( 0., tex.y) ) - + kernel[8] * sampleTexture( v_vTexcoord + vec2( tex.x, tex.y) ); + vec2 tex = 1. / dimension; + float sum = 1.; - gl_FragColor = vec4(c.rgb, 1.); + if(normalized == 1) { + sum = 0.; + int amo = size * size; + for(int i = 0; i < amo; i++) sum += kernel[i]; + } + + float st = -(float(size) - 1.) / 2.; + vec4 c = vec4(0.); + + for(int i = 0; i < size; i++) + for(int j = 0; j < size; j++) { + int index = i * size + j; + vec2 px = v_vTexcoord + vec2((float(j) + st) * tex.x, (float(i) + st) * tex.y); + + c += kernel[index] * sampleTexture(px) / sum; + } + + gl_FragColor = c; }