From 8e8435cd1493039a214e020692cfc77c9cb8bb77 Mon Sep 17 00:00:00 2001 From: Tanasart Date: Fri, 9 Feb 2024 20:43:03 +0700 Subject: [PATCH] - New Kuwahara filter node. --- PixelComposer.resource_order | 4 + PixelComposer.yyp | 4 + fonts/_f_sdf/_f_sdf.old.png | Bin 82361 -> 82361 bytes fonts/_f_sdf/_f_sdf.png | Bin 82361 -> 82361 bytes fonts/_f_sdf_medium/_f_sdf_medium.old.png | Bin 59906 -> 59906 bytes fonts/_f_sdf_medium/_f_sdf_medium.png | Bin 59906 -> 59906 bytes scripts/globals/globals.gml | 2 +- scripts/node_kuwahara/node_alpha_to_grey.yy | 12 ++ scripts/node_kuwahara/node_bw.yy | 12 ++ .../node_kuwahara/node_color_adjustment.yy | 12 ++ .../node_kuwahara/node_color_replacement.yy | 12 ++ scripts/node_kuwahara/node_greyscale.yy | 12 ++ scripts/node_kuwahara/node_kuwahara.gml | 28 +++++ scripts/node_kuwahara/node_kuwahara.yy | 11 ++ scripts/node_kuwahara/node_outline.yy | 12 ++ scripts/node_registry/node_registry.gml | 3 +- shaders/sh_kuwahara/sh_kuwahara.fsh | 109 ++++++++++++++++++ shaders/sh_kuwahara/sh_kuwahara.vsh | 18 +++ shaders/sh_kuwahara/sh_kuwahara.yy | 10 ++ shaders/sh_kuwahara_ani/sh_kuwahara_ani.fsh | 57 +++++++++ shaders/sh_kuwahara_ani/sh_kuwahara_ani.vsh | 18 +++ shaders/sh_kuwahara_ani/sh_kuwahara_ani.yy | 10 ++ .../d32dffb4-8395-4ac5-800e-6d35f00f9167.png | Bin 0 -> 2229 bytes .../7f08cf06-022b-4f31-ad2e-39f9ebdaa522.png | Bin 0 -> 2229 bytes sprites/s_node_kuwahara/s_node_kuwahara.yy | 74 ++++++++++++ 25 files changed, 418 insertions(+), 2 deletions(-) create mode 100644 scripts/node_kuwahara/node_alpha_to_grey.yy create mode 100644 scripts/node_kuwahara/node_bw.yy create mode 100644 scripts/node_kuwahara/node_color_adjustment.yy create mode 100644 scripts/node_kuwahara/node_color_replacement.yy create mode 100644 scripts/node_kuwahara/node_greyscale.yy create mode 100644 scripts/node_kuwahara/node_kuwahara.gml create mode 100644 scripts/node_kuwahara/node_kuwahara.yy create mode 100644 scripts/node_kuwahara/node_outline.yy create mode 100644 shaders/sh_kuwahara/sh_kuwahara.fsh create mode 100644 shaders/sh_kuwahara/sh_kuwahara.vsh create mode 100644 shaders/sh_kuwahara/sh_kuwahara.yy create mode 100644 shaders/sh_kuwahara_ani/sh_kuwahara_ani.fsh create mode 100644 shaders/sh_kuwahara_ani/sh_kuwahara_ani.vsh create mode 100644 shaders/sh_kuwahara_ani/sh_kuwahara_ani.yy create mode 100644 sprites/s_node_kuwahara/d32dffb4-8395-4ac5-800e-6d35f00f9167.png create mode 100644 sprites/s_node_kuwahara/layers/d32dffb4-8395-4ac5-800e-6d35f00f9167/7f08cf06-022b-4f31-ad2e-39f9ebdaa522.png create mode 100644 sprites/s_node_kuwahara/s_node_kuwahara.yy diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index 21697e871..3320deaf4 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -854,6 +854,7 @@ {"name":"s_node_3d_point_affector","order":21,"path":"sprites/s_node_3d_point_affector/s_node_3d_point_affector.yy",}, {"name":"polygon_points","order":2,"path":"scripts/polygon_points/polygon_points.yy",}, {"name":"transformBox","order":15,"path":"scripts/transformBox/transformBox.yy",}, + {"name":"sh_kuwahara","order":51,"path":"shaders/sh_kuwahara/sh_kuwahara.yy",}, {"name":"sh_grey_alpha","order":12,"path":"shaders/sh_grey_alpha/sh_grey_alpha.yy",}, {"name":"node_mk_cable","order":4,"path":"scripts/node_mk_cable/node_mk_cable.yy",}, {"name":"s_node_time_map","order":36,"path":"sprites/s_node_time_map/s_node_time_map.yy",}, @@ -899,6 +900,7 @@ {"name":"node_dust","order":3,"path":"scripts/node_dust/node_dust.yy",}, {"name":"node_noise_cell","order":2,"path":"scripts/node_noise_cell/node_noise_cell.yy",}, {"name":"s_node_pb_fx_radial","order":4,"path":"sprites/s_node_pb_fx_radial/s_node_pb_fx_radial.yy",}, + {"name":"node_kuwahara","order":21,"path":"scripts/node_kuwahara/node_kuwahara.yy",}, {"name":"__background_get_internal","order":2,"path":"scripts/__background_get_internal/__background_get_internal.yy",}, {"name":"s_node_array_sample","order":18,"path":"sprites/s_node_array_sample/s_node_array_sample.yy",}, {"name":"o_pie_menu","order":14,"path":"objects/o_pie_menu/o_pie_menu.yy",}, @@ -1311,6 +1313,7 @@ {"name":"__node_3d_mesh","order":1,"path":"scripts/__node_3d_mesh/__node_3d_mesh.yy",}, {"name":"d3d_surface_extrude","order":7,"path":"scripts/d3d_surface_extrude/d3d_surface_extrude.yy",}, {"name":"node_mesh_to_path","order":3,"path":"scripts/node_mesh_to_path/node_mesh_to_path.yy",}, + {"name":"sh_kuwahara_ani","order":52,"path":"shaders/sh_kuwahara_ani/sh_kuwahara_ani.yy",}, {"name":"sh_convolution","order":24,"path":"shaders/sh_convolution/sh_convolution.yy",}, {"name":"FirebaseREST_HTTP_Failed_Firestore","order":18,"path":"scripts/FirebaseREST_HTTP_Failed_Firestore/FirebaseREST_HTTP_Failed_Firestore.yy",}, {"name":"number_function","order":14,"path":"scripts/number_function/number_function.yy",}, @@ -1692,6 +1695,7 @@ {"name":"addon","order":1,"path":"objects/addon/addon.yy",}, {"name":"_f_h3","order":3,"path":"fonts/_f_h3/_f_h3.yy",}, {"name":"s_node_math","order":1,"path":"sprites/s_node_math/s_node_math.yy",}, + {"name":"s_node_kuwahara","order":59,"path":"sprites/s_node_kuwahara/s_node_kuwahara.yy",}, {"name":"panel_text_editor","order":11,"path":"scripts/panel_text_editor/panel_text_editor.yy",}, {"name":"node_path_bake","order":15,"path":"scripts/node_path_bake/node_path_bake.yy",}, {"name":"node_iterator_index","order":2,"path":"scripts/node_iterator_index/node_iterator_index.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index 0fb7d80a3..2d3be50f0 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -1126,6 +1126,7 @@ {"id":{"name":"s_node_3d_point_affector","path":"sprites/s_node_3d_point_affector/s_node_3d_point_affector.yy",},}, {"id":{"name":"polygon_points","path":"scripts/polygon_points/polygon_points.yy",},}, {"id":{"name":"transformBox","path":"scripts/transformBox/transformBox.yy",},}, + {"id":{"name":"sh_kuwahara","path":"shaders/sh_kuwahara/sh_kuwahara.yy",},}, {"id":{"name":"s_node_fluidSim_group","path":"sprites/s_node_fluidSim_group/s_node_fluidSim_group.yy",},}, {"id":{"name":"sh_grey_alpha","path":"shaders/sh_grey_alpha/sh_grey_alpha.yy",},}, {"id":{"name":"node_mk_cable","path":"scripts/node_mk_cable/node_mk_cable.yy",},}, @@ -1177,6 +1178,7 @@ {"id":{"name":"node_dust","path":"scripts/node_dust/node_dust.yy",},}, {"id":{"name":"node_noise_cell","path":"scripts/node_noise_cell/node_noise_cell.yy",},}, {"id":{"name":"s_node_pb_fx_radial","path":"sprites/s_node_pb_fx_radial/s_node_pb_fx_radial.yy",},}, + {"id":{"name":"node_kuwahara","path":"scripts/node_kuwahara/node_kuwahara.yy",},}, {"id":{"name":"__background_get_internal","path":"scripts/__background_get_internal/__background_get_internal.yy",},}, {"id":{"name":"s_node_array_sample","path":"sprites/s_node_array_sample/s_node_array_sample.yy",},}, {"id":{"name":"o_pie_menu","path":"objects/o_pie_menu/o_pie_menu.yy",},}, @@ -1642,6 +1644,7 @@ {"id":{"name":"sh_mk_tile18_edge_b","path":"shaders/sh_mk_tile18_edge_b/sh_mk_tile18_edge_b.yy",},}, {"id":{"name":"node_mesh_to_path","path":"scripts/node_mesh_to_path/node_mesh_to_path.yy",},}, {"id":{"name":"node_fluid_sim","path":"scripts/node_fluid_sim/node_fluid_sim.yy",},}, + {"id":{"name":"sh_kuwahara_ani","path":"shaders/sh_kuwahara_ani/sh_kuwahara_ani.yy",},}, {"id":{"name":"sh_convolution","path":"shaders/sh_convolution/sh_convolution.yy",},}, {"id":{"name":"FirebaseREST_HTTP_Failed_Firestore","path":"scripts/FirebaseREST_HTTP_Failed_Firestore/FirebaseREST_HTTP_Failed_Firestore.yy",},}, {"id":{"name":"number_function","path":"scripts/number_function/number_function.yy",},}, @@ -2083,6 +2086,7 @@ {"id":{"name":"string_decimal","path":"scripts/string_decimal/string_decimal.yy",},}, {"id":{"name":"_f_h3","path":"fonts/_f_h3/_f_h3.yy",},}, {"id":{"name":"s_node_math","path":"sprites/s_node_math/s_node_math.yy",},}, + {"id":{"name":"s_node_kuwahara","path":"sprites/s_node_kuwahara/s_node_kuwahara.yy",},}, {"id":{"name":"panel_text_editor","path":"scripts/panel_text_editor/panel_text_editor.yy",},}, {"id":{"name":"node_path_bake","path":"scripts/node_path_bake/node_path_bake.yy",},}, {"id":{"name":"node_iterator_index","path":"scripts/node_iterator_index/node_iterator_index.yy",},}, diff --git a/fonts/_f_sdf/_f_sdf.old.png b/fonts/_f_sdf/_f_sdf.old.png index 53785fa03d0409431ef5501e6008aec7fa3b7daa..ee1ed111b251bb88e789b4b8c32b63d0ac9ffcbc 100644 GIT binary patch delta 96 zcmdnl%(}CgwP6dRiKB=`h@qjCv9XnrfwqBxm4Si!=e`5eJscTjF=WElnbl0MbYxUe WK-a^#TYNDC5O})!xvXVh=G}vskxP*v9^JMm4U&8KQSMsdpI)6V#qvP_{3*=r6Z$) W0=k}UTaHd<00K`}KbLh*2~7ZSN*rqd diff --git a/fonts/_f_sdf/_f_sdf.png b/fonts/_f_sdf/_f_sdf.png index d3558121933fbb126af804ae43f101651820a7b9..ca4a04dfa904a3bb19ed1709e0f24167d7016a7c 100644 GIT binary patch delta 96 zcmdnl%(}CgwP6dRiKB>Rh@p{{v9Xo0fwqBxm4U&J-^Gm6JscTjF=RTIo!&dW(veX? W0bS3%&99OefWXt$&t;ucLK6T}9UKS% delta 96 zcmdnl%(}CgwP6dRiKB>Fh@qjCsfCq+p|*j6m4U(MGFP$b9*&H%7&1-Te^*VfbYxUe WK-Y8C?oKHK5O})!xvX5sMH*Ln~urDjH?_DVF}Hxh$iT=%*T6{E09_B`Zt=xHJq(_%elF{r5}E+eks{jw delta 119 zcmZp=!rXL)c|+|>5z`O@Gb>YbD??*#0|P4qg9(3PK1`nYQZ@u#;^D$4J`4;D8YQj~ vB`Jv|sa7SKxv9k^iMa&~Mg~SEx&}tN2IzXWZ85z7!mBP(NLD`Nv~0|P4qgCD<(87EJCDI0<=(YfsOUIqpRjS|<0 vl9a@fRI8HA+|=Td#M}Y~BLgE7T>~Rs19Uz2Hor;&>S6G7^>bP0l+XkKEhHsN delta 119 zcmZp=!rXL)c|+|>5wj3OLn~7YD+5Dq0|P4qgU@BIVv{Gnlnp_bXwv?>ih+Saqr^3$ uBqgyV)v6>jH?_DVF}Hxh$iT=%*T6{E0A0^jyE~;oJq(_%elF{r5}E+f>m$zq diff --git a/scripts/globals/globals.gml b/scripts/globals/globals.gml index 2421cfcc0..79fae4b42 100644 --- a/scripts/globals/globals.gml +++ b/scripts/globals/globals.gml @@ -13,7 +13,7 @@ randomize(); #endregion -#region main +#region ======================================================================= MAIN ======================================================================= globalvar OS, DEBUG, THEME, COLOR_KEYS; globalvar CMD, CMDIN; diff --git a/scripts/node_kuwahara/node_alpha_to_grey.yy b/scripts/node_kuwahara/node_alpha_to_grey.yy new file mode 100644 index 000000000..fde448fca --- /dev/null +++ b/scripts/node_kuwahara/node_alpha_to_grey.yy @@ -0,0 +1,12 @@ +{ + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "filter", + "path": "folders/nodes/data/filter.yy", + }, + "resourceVersion": "1.0", + "name": "node_alpha_to_grey", + "tags": [], + "resourceType": "GMScript", +} \ No newline at end of file diff --git a/scripts/node_kuwahara/node_bw.yy b/scripts/node_kuwahara/node_bw.yy new file mode 100644 index 000000000..6d2681493 --- /dev/null +++ b/scripts/node_kuwahara/node_bw.yy @@ -0,0 +1,12 @@ +{ + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "filter", + "path": "folders/nodes/data/filter.yy", + }, + "resourceVersion": "1.0", + "name": "node_bw", + "tags": [], + "resourceType": "GMScript", +} \ No newline at end of file diff --git a/scripts/node_kuwahara/node_color_adjustment.yy b/scripts/node_kuwahara/node_color_adjustment.yy new file mode 100644 index 000000000..8df16cc8c --- /dev/null +++ b/scripts/node_kuwahara/node_color_adjustment.yy @@ -0,0 +1,12 @@ +{ + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "filter", + "path": "folders/nodes/data/filter.yy", + }, + "resourceVersion": "1.0", + "name": "node_color_adjustment", + "tags": [], + "resourceType": "GMScript", +} \ No newline at end of file diff --git a/scripts/node_kuwahara/node_color_replacement.yy b/scripts/node_kuwahara/node_color_replacement.yy new file mode 100644 index 000000000..024aa6a80 --- /dev/null +++ b/scripts/node_kuwahara/node_color_replacement.yy @@ -0,0 +1,12 @@ +{ + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "process", + "path": "folders/nodes/data/process.yy", + }, + "resourceVersion": "1.0", + "name": "node_color_replacement", + "tags": [], + "resourceType": "GMScript", +} \ No newline at end of file diff --git a/scripts/node_kuwahara/node_greyscale.yy b/scripts/node_kuwahara/node_greyscale.yy new file mode 100644 index 000000000..ee372977e --- /dev/null +++ b/scripts/node_kuwahara/node_greyscale.yy @@ -0,0 +1,12 @@ +{ + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "filter", + "path": "folders/nodes/data/filter.yy", + }, + "resourceVersion": "1.0", + "name": "node_greyscale", + "tags": [], + "resourceType": "GMScript", +} \ No newline at end of file diff --git a/scripts/node_kuwahara/node_kuwahara.gml b/scripts/node_kuwahara/node_kuwahara.gml new file mode 100644 index 000000000..da41346bc --- /dev/null +++ b/scripts/node_kuwahara/node_kuwahara.gml @@ -0,0 +1,28 @@ +function Node_Kuwahara(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { + name = "Kuwahara"; + + inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, 0); + + inputs[| 1] = nodeValue("Active", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); + active_index = 1; + + inputs[| 2] = nodeValue("Radius", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 2); + + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + input_display_list = [ 1, 0, 2 ]; + + attribute_surface_depth(); + + static processData = function(_outSurf, _data, _output_index, _array_index) { #region + + surface_set_shader(_outSurf, sh_kuwahara); + shader_set_f("dimension", surface_get_dimension(_data[0])); + shader_set_i("radius", _data[2]); + + draw_surface_safe(_data[0]); + surface_reset_shader(); + + return _outSurf; + } #endregion +} \ No newline at end of file diff --git a/scripts/node_kuwahara/node_kuwahara.yy b/scripts/node_kuwahara/node_kuwahara.yy new file mode 100644 index 000000000..6c594b276 --- /dev/null +++ b/scripts/node_kuwahara/node_kuwahara.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "node_kuwahara", + "isCompatibility": false, + "isDnD": false, + "parent": { + "name": "effects", + "path": "folders/nodes/data/filter/effects.yy", + }, +} \ No newline at end of file diff --git a/scripts/node_kuwahara/node_outline.yy b/scripts/node_kuwahara/node_outline.yy new file mode 100644 index 000000000..86468bc09 --- /dev/null +++ b/scripts/node_kuwahara/node_outline.yy @@ -0,0 +1,12 @@ +{ + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "process", + "path": "folders/nodes/data/process.yy", + }, + "resourceVersion": "1.0", + "name": "node_outline", + "tags": [], + "resourceType": "GMScript", +} \ No newline at end of file diff --git a/scripts/node_registry/node_registry.gml b/scripts/node_registry/node_registry.gml index 439d42f42..1bc33c112 100644 --- a/scripts/node_registry/node_registry.gml +++ b/scripts/node_registry/node_registry.gml @@ -538,6 +538,7 @@ function __initNodes() { addNodeObject(filter, "Chromatic Aberration", s_node_chromatic_abarration, "Node_Chromatic_Aberration", [1, Node_Chromatic_Aberration],, "Apply chromatic aberration effect to the image."); addNodeObject(filter, "Vignette", s_node_vignette, "Node_Vignette", [1, Node_Vignette],, "Apply vignette effect to the border.").setVersion(11630); addNodeObject(filter, "FXAA", s_node_FXAA, "Node_FXAA", [1, Node_FXAA],, "Apply fast approximate anti-aliasing to the image."); + addNodeObject(filter, "Kuwahara", s_node_kuwahara, "Node_Kuwahara", [1, Node_Kuwahara]); //addNodeObject(filter, "Blend Edge", s_node_FXAA, "Node_Blend_Edge", [1, Node_Blend_Edge]).setVersion(11640); ds_list_add(filter, "Colors"); @@ -936,7 +937,7 @@ function __initNodes() { var actions = ds_list_create(); addNodeCatagory("Action", actions); __initNodeActions(actions); - + var customs = ds_list_create(); addNodeCatagory("Custom", customs); __initNodeCustom(customs); diff --git a/shaders/sh_kuwahara/sh_kuwahara.fsh b/shaders/sh_kuwahara/sh_kuwahara.fsh new file mode 100644 index 000000000..9fe601ce8 --- /dev/null +++ b/shaders/sh_kuwahara/sh_kuwahara.fsh @@ -0,0 +1,109 @@ +/* +Generalized Kuwahara filter, based on work of Acerola +Basically Acerola code rewritten to Shadertoy +- https://www.youtube.com/watch?v=LDhN-JK3U9g +- https://github.com/GarrettGunnell/Post-Processing/tree/main/Assets/Kuwahara%20Filter +*/ + +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +#define PI 3.14159265358979323846; +#define MAX_RAD 64 + +const float q = 18.; + +uniform vec2 dimension; +uniform int radius; + +void main () { + vec2 tx = 1. / dimension; + float zeta = 2. / float(radius); + float zeroCross = 2.; + + float sinZeroCross = sin(zeroCross); + float eta = 0.; + vec4 m[8]; + vec3 s[8]; + + for (int k = 0; k < 8; ++k) { + m[k] = vec4(0.); + s[k] = vec3(0.); + } + + for (int y = -MAX_RAD; y <= MAX_RAD; y++) + for (int x = -MAX_RAD; x <= MAX_RAD; x++) { + if(y < -radius) continue; + if(x < -radius) continue; + if(x > radius) continue; + if(y > radius) break; + + vec2 v = vec2(x, y) / float(radius); + vec3 c = texture2D( gm_BaseTexture, v_vTexcoord + vec2(x, y) * tx).xyz; + c = clamp(c, 0., 1.); + float sum = 0.; + + float w[8]; + float z, vxx, vyy; + + /* Calculate Polynomial Weights */ + vxx = zeta - eta * v.x * v.x; + vyy = zeta - eta * v.y * v.y; + z = max(0., v.y + vxx); + w[0] = z * z; + sum += w[0]; + z = max(0., -v.x + vyy); + + w[2] = z * z; + sum += w[2]; + z = max(0., -v.y + vxx); + + w[4] = z * z; + sum += w[4]; + z = max(0., v.x + vyy); + + w[6] = z * z; + sum += w[6]; + v = sqrt(2.0) / 2.0 * vec2(v.x - v.y, v.x + v.y); + vxx = zeta - eta * v.x * v.x; + vyy = zeta - eta * v.y * v.y; + + z = max(0., v.y + vxx); + w[1] = z * z; + sum += w[1]; + + z = max(0., -v.x + vyy); + w[3] = z * z; + sum += w[3]; + + z = max(0., -v.y + vxx); + w[5] = z * z; + sum += w[5]; + + z = max(0., v.x + vyy); + w[7] = z * z; + sum += w[7]; + + float g = exp(-3.125 * dot(v, v)) / (sum + 0.0001); + + for (int k = 0; k < 8; k++) { + float wk = w[k] * g; + m[k] += vec4(c * wk, wk); + s[k] += c * c * wk; + } + } + + vec4 ou = vec4(0.); + + for (int k = 0; k < 8; k++) { + m[k].rgb /= m[k].w; + s[k] = abs(s[k] / m[k].w - m[k].rgb * m[k].rgb); + + float sigma2 = s[k].r + s[k].g + s[k].b; + float w = 1.0 / (1.0 + pow(1000.0 * sigma2, 0.5 * q)); + + ou += vec4(m[k].rgb * w, w); + } + + gl_FragColor = clamp((ou / ou.w), 0.0, 1.0); +} \ No newline at end of file diff --git a/shaders/sh_kuwahara/sh_kuwahara.vsh b/shaders/sh_kuwahara/sh_kuwahara.vsh new file mode 100644 index 000000000..d4b316559 --- /dev/null +++ b/shaders/sh_kuwahara/sh_kuwahara.vsh @@ -0,0 +1,18 @@ +// +// Simple passthrough vertex shader +// +attribute vec3 in_Position; // (x,y,z) +//attribute vec3 in_Normal; // (x,y,z) unused in this shader. +attribute vec4 in_Colour; // (r,g,b,a) +attribute vec2 in_TextureCoord; // (u,v) + +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +void main() { + vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0); + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos; + + v_vColour = in_Colour; + v_vTexcoord = in_TextureCoord; +} diff --git a/shaders/sh_kuwahara/sh_kuwahara.yy b/shaders/sh_kuwahara/sh_kuwahara.yy new file mode 100644 index 000000000..2245fc940 --- /dev/null +++ b/shaders/sh_kuwahara/sh_kuwahara.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "sh_kuwahara", + "parent": { + "name": "filter", + "path": "folders/shader/filter.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/shaders/sh_kuwahara_ani/sh_kuwahara_ani.fsh b/shaders/sh_kuwahara_ani/sh_kuwahara_ani.fsh new file mode 100644 index 000000000..622dc2925 --- /dev/null +++ b/shaders/sh_kuwahara_ani/sh_kuwahara_ani.fsh @@ -0,0 +1,57 @@ +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +#define MAX_RAD 64 + +uniform vec2 dimension; +uniform int radius; + +void main () { + gl_FragColor = texture2D(gm_BaseTexture, v_vTexcoord); + + vec2 tx = 1. / dimension; + float n = float((radius + 1) * (radius + 1)); + + vec3 m[4]; + vec3 s[4]; + vec3 c; + + for (int k = 0; k < 4; ++k) { + m[k] = vec3(0.0); + s[k] = vec3(0.0); + } + + for (int j = 0; j <= MAX_RAD; j++) + for (int i = 0; i <= MAX_RAD; i++) { + if(i > radius) continue; + if(j > radius) break; + + c = texture2D(gm_BaseTexture, v_vTexcoord + vec2(-i, -j) * tx).rgb; + m[0] += c; + s[0] += c * c; + + c = texture2D(gm_BaseTexture, v_vTexcoord + vec2( i, -j) * tx).rgb; + m[1] += c; + s[1] += c * c; + + c = texture2D(gm_BaseTexture, v_vTexcoord + vec2( i, j) * tx).rgb; + m[2] += c; + s[2] += c * c; + + c = texture2D(gm_BaseTexture, v_vTexcoord + vec2(-i, j) * tx).rgb; + m[3] += c; + s[3] += c * c; + } + + float min_sigma2 = 100.; + for (int k = 0; k < 4; k++) { + m[k] /= n; + s[k] = abs(s[k] / n - m[k] * m[k]); + + float sigma2 = s[k].r + s[k].g + s[k].b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + gl_FragColor = vec4(m[k], 1.0); + } + } +} \ No newline at end of file diff --git a/shaders/sh_kuwahara_ani/sh_kuwahara_ani.vsh b/shaders/sh_kuwahara_ani/sh_kuwahara_ani.vsh new file mode 100644 index 000000000..d4b316559 --- /dev/null +++ b/shaders/sh_kuwahara_ani/sh_kuwahara_ani.vsh @@ -0,0 +1,18 @@ +// +// Simple passthrough vertex shader +// +attribute vec3 in_Position; // (x,y,z) +//attribute vec3 in_Normal; // (x,y,z) unused in this shader. +attribute vec4 in_Colour; // (r,g,b,a) +attribute vec2 in_TextureCoord; // (u,v) + +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +void main() { + vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0); + gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos; + + v_vColour = in_Colour; + v_vTexcoord = in_TextureCoord; +} diff --git a/shaders/sh_kuwahara_ani/sh_kuwahara_ani.yy b/shaders/sh_kuwahara_ani/sh_kuwahara_ani.yy new file mode 100644 index 000000000..971120ecf --- /dev/null +++ b/shaders/sh_kuwahara_ani/sh_kuwahara_ani.yy @@ -0,0 +1,10 @@ +{ + "resourceType": "GMShader", + "resourceVersion": "1.0", + "name": "sh_kuwahara_ani", + "parent": { + "name": "filter", + "path": "folders/shader/filter.yy", + }, + "type": 1, +} \ No newline at end of file diff --git a/sprites/s_node_kuwahara/d32dffb4-8395-4ac5-800e-6d35f00f9167.png b/sprites/s_node_kuwahara/d32dffb4-8395-4ac5-800e-6d35f00f9167.png new file mode 100644 index 0000000000000000000000000000000000000000..1488f077f836de92ec57608ee43051e60f0ee4e9 GIT binary patch literal 2229 zcmZ{ldo&aLAIHBN)sQTNJaS8;qLy3Q+*xf;+guuvd)Q=@Yi|8)u7zJN2}Oj}L#i>= zQ!E*e@F<$l+#_MRGnXPf>!05_zdxSyIiK(QoX_X``h3pke9!rQQf!H5B*hiQ0RWOX zthK#R&3`#;r|_(}6g(^xRd1|40f1-(0Q5uv)`cNDAAoQq08^d-pzZ)5A9SzQ&RCe( zdGYKSYq0&xitEa<0oYZJv$h~b_RqSU4ILmUn0$Jdt7Jf&y3?JE3LL`gJ%7HNyF*V_ z_r1Bi_PR`)*|ZHm9^;%-J;N(R)wWY3= zRTVO}({Vob=G(A-fl&);Q6DA+gsI4%{FsU0hWRE&yp}lp&|c#fHN+XO{BV*K^~T#$ zKSP%)ZR(TH+mrM4f5{*T5A+UeoD*O*NE-4J8)H#V0q}dF?TXd38`SaIe0kpQrH=lT z}jj!~*=SP8_kgrhZSC30mj@Pf>K76fiI7mz-4Y#L+WH7v~yh~j5YvGPQj)V5sTPfEsp-4B6;Tv%EPFCayV5mTHix(eBJn6{aC1Und&JBr!gI}> zcMTNx1wet~%{iLAL}byKIsa83c&1z1$g|_7iz{>OMR0wx%#q=l87aA@;LLGmwEUl` zfU}!cEp3GobSz3E3v3rVXQ$u%>YilTX~5Jvp%Kj{q<0>%iSLGjSDCn*<5JD)o`xk~ zI;Lhz8e=SOS>Llk40hP2*G}Y^gGwAePWVwS5RsiT-Xgj&!hm z%7(Uv{Git(`$x6S{s!LsE8+ctGyA0C_rgo@d+>Cvq|n%&zg}AP^fwPo1+84(gG)S( z@r2$|GvGX?v!-LDbA3zfBGO+D1oD*R8k;w>#9$&;C-+)384y2h8n!*OI=>^*DVY49 ztM;U0>~_j&2Ul-auPmM;@dVK_?EZJ?V0Az9MCAlxR#UOA=}})$fkihXcEr-}t&?cC zg2_5Ekcw(qg9fT=O#QK;K=notficR#t>CgKYKYrz9{Sjn_;K1v;rjkNpc39aCwlJE z#1|37N%tBnnxyikWq%4W5q!u#IM;O({*oDALF+AGtf=Wc&w^hyq9P)WUFv2+66W1H!E6=jLiQmozYN5S2SmvuC?SexQdf3O*m}!DjaHEW{5;X7OgR$ouarA+$I`Oj8b>DgkwF-=$ z`U_8QF2Cnsqc}D;G~WuHz5yO}r^P4LJ+D`SNc$?dC4qMXTDgrbxjSZ8>KQk56(P~> zoQ#b7t2oswP9N81c(mz!{58ZUk0*JBA9IwQZBt4)0WA;?ITjtXZn76jpG(iu=)Lhf z5t_>0#SLfB&}sX&j#v*@)t?W6Sr0?YB51Tq*?xgdBFGnYk$6zf_qYGKBzU()k%M5= zFLI%*In2y_&S}TZ6u4*h0-vqfN=-5q`+cx)L_1*iB6||x<*xnLSc>ZA)`B@UhhF4V*sAkGAcl60CHZyUvnyABkUViCXG1C4Uh37ZEd2cL+ zF`T&iVWO!>x`6K;@^(n%`jIXT$pKcojgphkNGJ4A`bH?^iK9p)3W*Fs^cnsi5O~Gs5;^MM0g)K5R3V`CzYbxS c0)0cnyaI#%ogrN|cMviFhap-sEj{D^0l`8J{{R30 literal 0 HcmV?d00001 diff --git a/sprites/s_node_kuwahara/layers/d32dffb4-8395-4ac5-800e-6d35f00f9167/7f08cf06-022b-4f31-ad2e-39f9ebdaa522.png b/sprites/s_node_kuwahara/layers/d32dffb4-8395-4ac5-800e-6d35f00f9167/7f08cf06-022b-4f31-ad2e-39f9ebdaa522.png new file mode 100644 index 0000000000000000000000000000000000000000..1488f077f836de92ec57608ee43051e60f0ee4e9 GIT binary patch literal 2229 zcmZ{ldo&aLAIHBN)sQTNJaS8;qLy3Q+*xf;+guuvd)Q=@Yi|8)u7zJN2}Oj}L#i>= zQ!E*e@F<$l+#_MRGnXPf>!05_zdxSyIiK(QoX_X``h3pke9!rQQf!H5B*hiQ0RWOX zthK#R&3`#;r|_(}6g(^xRd1|40f1-(0Q5uv)`cNDAAoQq08^d-pzZ)5A9SzQ&RCe( zdGYKSYq0&xitEa<0oYZJv$h~b_RqSU4ILmUn0$Jdt7Jf&y3?JE3LL`gJ%7HNyF*V_ z_r1Bi_PR`)*|ZHm9^;%-J;N(R)wWY3= zRTVO}({Vob=G(A-fl&);Q6DA+gsI4%{FsU0hWRE&yp}lp&|c#fHN+XO{BV*K^~T#$ zKSP%)ZR(TH+mrM4f5{*T5A+UeoD*O*NE-4J8)H#V0q}dF?TXd38`SaIe0kpQrH=lT z}jj!~*=SP8_kgrhZSC30mj@Pf>K76fiI7mz-4Y#L+WH7v~yh~j5YvGPQj)V5sTPfEsp-4B6;Tv%EPFCayV5mTHix(eBJn6{aC1Und&JBr!gI}> zcMTNx1wet~%{iLAL}byKIsa83c&1z1$g|_7iz{>OMR0wx%#q=l87aA@;LLGmwEUl` zfU}!cEp3GobSz3E3v3rVXQ$u%>YilTX~5Jvp%Kj{q<0>%iSLGjSDCn*<5JD)o`xk~ zI;Lhz8e=SOS>Llk40hP2*G}Y^gGwAePWVwS5RsiT-Xgj&!hm z%7(Uv{Git(`$x6S{s!LsE8+ctGyA0C_rgo@d+>Cvq|n%&zg}AP^fwPo1+84(gG)S( z@r2$|GvGX?v!-LDbA3zfBGO+D1oD*R8k;w>#9$&;C-+)384y2h8n!*OI=>^*DVY49 ztM;U0>~_j&2Ul-auPmM;@dVK_?EZJ?V0Az9MCAlxR#UOA=}})$fkihXcEr-}t&?cC zg2_5Ekcw(qg9fT=O#QK;K=notficR#t>CgKYKYrz9{Sjn_;K1v;rjkNpc39aCwlJE z#1|37N%tBnnxyikWq%4W5q!u#IM;O({*oDALF+AGtf=Wc&w^hyq9P)WUFv2+66W1H!E6=jLiQmozYN5S2SmvuC?SexQdf3O*m}!DjaHEW{5;X7OgR$ouarA+$I`Oj8b>DgkwF-=$ z`U_8QF2Cnsqc}D;G~WuHz5yO}r^P4LJ+D`SNc$?dC4qMXTDgrbxjSZ8>KQk56(P~> zoQ#b7t2oswP9N81c(mz!{58ZUk0*JBA9IwQZBt4)0WA;?ITjtXZn76jpG(iu=)Lhf z5t_>0#SLfB&}sX&j#v*@)t?W6Sr0?YB51Tq*?xgdBFGnYk$6zf_qYGKBzU()k%M5= zFLI%*In2y_&S}TZ6u4*h0-vqfN=-5q`+cx)L_1*iB6||x<*xnLSc>ZA)`B@UhhF4V*sAkGAcl60CHZyUvnyABkUViCXG1C4Uh37ZEd2cL+ zF`T&iVWO!>x`6K;@^(n%`jIXT$pKcojgphkNGJ4A`bH?^iK9p)3W*Fs^cnsi5O~Gs5;^MM0g)K5R3V`CzYbxS c0)0cnyaI#%ogrN|cMviFhap-sEj{D^0l`8J{{R30 literal 0 HcmV?d00001 diff --git a/sprites/s_node_kuwahara/s_node_kuwahara.yy b/sprites/s_node_kuwahara/s_node_kuwahara.yy new file mode 100644 index 000000000..4a2d383f1 --- /dev/null +++ b/sprites/s_node_kuwahara/s_node_kuwahara.yy @@ -0,0 +1,74 @@ +{ + "resourceType": "GMSprite", + "resourceVersion": "1.0", + "name": "s_node_kuwahara", + "bbox_bottom": 63, + "bbox_left": 0, + "bbox_right": 63, + "bbox_top": 0, + "bboxMode": 0, + "collisionKind": 1, + "collisionTolerance": 0, + "DynamicTexturePage": false, + "edgeFiltering": false, + "For3D": false, + "frames": [ + {"resourceType":"GMSpriteFrame","resourceVersion":"1.1","name":"d32dffb4-8395-4ac5-800e-6d35f00f9167",}, + ], + "gridX": 0, + "gridY": 0, + "height": 64, + "HTile": false, + "layers": [ + {"resourceType":"GMImageLayer","resourceVersion":"1.0","name":"7f08cf06-022b-4f31-ad2e-39f9ebdaa522","blendMode":0,"displayName":"default","isLocked":false,"opacity":100.0,"visible":true,}, + ], + "nineSlice": null, + "origin": 4, + "parent": { + "name": "filter", + "path": "folders/nodes/icons/filter.yy", + }, + "preMultiplyAlpha": false, + "sequence": { + "resourceType": "GMSequence", + "resourceVersion": "1.4", + "name": "s_node_kuwahara", + "autoRecord": true, + "backdropHeight": 768, + "backdropImageOpacity": 0.5, + "backdropImagePath": "", + "backdropWidth": 1366, + "backdropXOffset": 0.0, + "backdropYOffset": 0.0, + "events": {"resourceType":"KeyframeStore","resourceVersion":"1.0","Keyframes":[],}, + "eventStubScript": null, + "eventToFunction": {}, + "length": 1.0, + "lockOrigin": false, + "moments": {"resourceType":"KeyframeStore","resourceVersion":"1.0","Keyframes":[],}, + "playback": 1, + "playbackSpeed": 30.0, + "playbackSpeedType": 0, + "showBackdrop": true, + "showBackdropImage": false, + "timeUnits": 1, + "tracks": [ + {"resourceType":"GMSpriteFramesTrack","resourceVersion":"1.0","name":"frames","builtinName":0,"events":[],"inheritsTrackColour":true,"interpolation":1,"isCreationTrack":false,"keyframes":{"resourceType":"KeyframeStore","resourceVersion":"1.0","Keyframes":[ + {"resourceType":"Keyframe","resourceVersion":"1.0","Channels":{"0":{"resourceType":"SpriteFrameKeyframe","resourceVersion":"1.0","Id":{"name":"d32dffb4-8395-4ac5-800e-6d35f00f9167","path":"sprites/s_node_kuwahara/s_node_kuwahara.yy",},},},"Disabled":false,"id":"e7a17aeb-e2e6-4c0b-a6aa-ec494d2715ae","IsCreationKey":false,"Key":0.0,"Length":1.0,"Stretch":false,}, + ],},"modifiers":[],"spriteId":null,"trackColour":0,"tracks":[],"traits":0,}, + ], + "visibleRange": null, + "volume": 1.0, + "xorigin": 32, + "yorigin": 32, + }, + "swatchColours": null, + "swfPrecision": 2.525, + "textureGroupId": { + "name": "Default", + "path": "texturegroups/Default", + }, + "type": 0, + "VTile": false, + "width": 64, +} \ No newline at end of file