[Convolute] Add normalize option, custom kernel size.

This commit is contained in:
Tanasart 2024-10-05 15:30:21 +07:00
parent 177d4968b3
commit 31a4e7e658
6 changed files with 84 additions and 68 deletions

View file

@ -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]);
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;
}
static setInteract = function(interactable = noone) {
return self;
} setSize(_size);
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;
}
}

View file

@ -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;

View file

@ -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_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();

View file

@ -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;

View file

@ -1,6 +1,7 @@
function textInput(_input, _onModify) : widget() constructor {
input = _input;
onModify = _onModify;
onModifyParam = noone;
selecting = false;
auto_update = false;

View file

@ -4,9 +4,11 @@
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
uniform int size;
uniform vec2 dimension;
uniform float kernel[9];
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.)
@ -29,17 +31,24 @@ 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) )
float sum = 1.;
+ 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) );
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;
}