diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index 3ee43dc58..18f73ad09 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -261,6 +261,7 @@ {"name":"rotator","order":2,"path":"folders/widgets/rotator.yy",}, {"name":"sliders","order":3,"path":"folders/widgets/sliders.yy",}, {"name":"text","order":4,"path":"folders/widgets/text.yy",}, + {"name":"threshold","order":23,"path":"folders/nodes/data/filter/colors/threshold.yy",}, ], "ResourceOrderSettings":[ {"name":"ac_disappear","order":2,"path":"animcurves/ac_disappear/ac_disappear.yy",}, @@ -1772,7 +1773,6 @@ {"name":"sh_texture_atlas","order":2,"path":"shaders/sh_texture_atlas/sh_texture_atlas.yy",}, {"name":"sh_texture_remap","order":5,"path":"shaders/sh_texture_remap/sh_texture_remap.yy",}, {"name":"sh_texture_repeat","order":21,"path":"shaders/sh_texture_repeat/sh_texture_repeat.yy",}, - {"name":"sh_threshold","order":23,"path":"shaders/sh_threshold/sh_threshold.yy",}, {"name":"sh_tile_random","order":26,"path":"shaders/sh_tile_random/sh_tile_random.yy",}, {"name":"sh_tile_rule_apply","order":9,"path":"shaders/sh_tile_rule_apply/sh_tile_rule_apply.yy",}, {"name":"sh_tile_rule_select","order":10,"path":"shaders/sh_tile_rule_select/sh_tile_rule_select.yy",}, @@ -2862,5 +2862,6 @@ {"name":"workshop_badge","order":42,"path":"sprites/workshop_badge/workshop_badge.yy",}, {"name":"workshop_bg","order":43,"path":"sprites/workshop_bg/workshop_bg.yy",}, {"name":"workshop_frame","order":44,"path":"sprites/workshop_frame/workshop_frame.yy",}, + {"name":"sh_threshold_adaptive","order":1,"path":"shaders/sh_threshold_adaptive/sh_threshold_adaptive.yy",}, ], } \ No newline at end of file diff --git a/PixelComposer.yyp b/PixelComposer.yyp index 866865696..c28ca2774 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -338,6 +338,7 @@ {"$GMFolder":"","%Name":"rotator","folderPath":"folders/widgets/rotator.yy","name":"rotator","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"sliders","folderPath":"folders/widgets/sliders.yy","name":"sliders","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"text","folderPath":"folders/widgets/text.yy","name":"text","resourceType":"GMFolder","resourceVersion":"2.0",}, + {"$GMFolder":"","%Name":"threshold","folderPath":"folders/nodes/data/filter/colors/threshold.yy","name":"threshold","resourceType":"GMFolder","resourceVersion":"2.0",}, ], "IncludedFiles":[ {"$GMIncludedFile":"","%Name":"Actions.zip","CopyToMask":-1,"filePath":"datafiles/data","name":"Actions.zip","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, @@ -569,11 +570,7 @@ {"$GMIncludedFile":"","%Name":"Node_Warp.png","CopyToMask":-1,"filePath":"datafiles/data/Tooltip","name":"Node_Warp.png","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"Node_Wavelet_Noise.png","CopyToMask":-1,"filePath":"datafiles/data/Tooltip","name":"Node_Wavelet_Noise.png","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"Node_Zigzag.png","CopyToMask":-1,"filePath":"datafiles/data/Tooltip","name":"Node_Zigzag.png","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, - {"$GMIncludedFile":"","%Name":"dllcredits.txt","ConfigValues":{ - "Itch":{ - "CopyToMask":"0", - }, - },"CopyToMask":0,"filePath":"datafiles","name":"dllcredits.txt","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, + {"$GMIncludedFile":"","%Name":"dllcredits.txt","ConfigValues":{"Itch":{"CopyToMask":"0",},},"CopyToMask":0,"filePath":"datafiles","name":"dllcredits.txt","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"dlltest1.dll","CopyToMask":-1,"filePath":"datafiles","name":"dlltest1.dll","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"ffmpeg.exe","CopyToMask":-1,"filePath":"datafiles/ffmpeg/bin","name":"ffmpeg.exe","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"LICENSE","CopyToMask":-1,"filePath":"datafiles/ffmpeg","name":"LICENSE","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, @@ -592,11 +589,7 @@ {"$GMIncludedFile":"","%Name":"mf.dll","CopyToMask":-1,"filePath":"datafiles","name":"mf.dll","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"mfcore.dll","CopyToMask":-1,"filePath":"datafiles","name":"mfcore.dll","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"mfplat.dll","CopyToMask":-1,"filePath":"datafiles","name":"mfplat.dll","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, - {"$GMIncludedFile":"","%Name":"PixelComposer_profile-2.provisionprofile","ConfigValues":{ - "Itch":{ - "CopyToMask":"2", - }, - },"CopyToMask":-1,"filePath":"datafiles","name":"PixelComposer_profile-2.provisionprofile","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, + {"$GMIncludedFile":"","%Name":"PixelComposer_profile-2.provisionprofile","ConfigValues":{"Itch":{"CopyToMask":"2",},},"CopyToMask":-1,"filePath":"datafiles","name":"PixelComposer_profile-2.provisionprofile","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"data.win","CopyToMask":-1,"filePath":"datafiles/report","name":"data.win","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"execute_shell_simple_ext_x64.dll","CopyToMask":-1,"filePath":"datafiles/report","name":"execute_shell_simple_ext_x64.dll","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"options.ini","CopyToMask":-1,"filePath":"datafiles/report","name":"options.ini","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, @@ -1242,6 +1235,7 @@ {"id":{"name":"node_atlas_get","path":"scripts/node_atlas_get/node_atlas_get.yy",},}, {"id":{"name":"node_atlas_set","path":"scripts/node_atlas_set/node_atlas_set.yy",},}, {"id":{"name":"node_atlas_to_struct","path":"scripts/node_atlas_to_struct/node_atlas_to_struct.yy",},}, + {"id":{"name":"sh_threshold_adaptive","path":"shaders/sh_threshold_adaptive/sh_threshold_adaptive.yy",},}, {"id":{"name":"node_atlas","path":"scripts/node_atlas/node_atlas.yy",},}, {"id":{"name":"node_attributes","path":"scripts/node_attributes/node_attributes.yy",},}, {"id":{"name":"node_audio_loudness","path":"scripts/node_audio_loudness/node_audio_loudness.yy",},}, diff --git a/scripts/node_bw/node_bw.gml b/scripts/node_bw/node_bw.gml index 6dca47fe4..49f69f3f2 100644 --- a/scripts/node_bw/node_bw.gml +++ b/scripts/node_bw/node_bw.gml @@ -40,14 +40,14 @@ function Node_BW(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constr attribute_surface_depth(); - static step = function() { #region + static step = function() { __step_mask_modifier(); inputs[1].mappableStep(); inputs[2].mappableStep(); - } #endregion + } - static processData = function(_outSurf, _data, _output_index, _array_index) { #region + static processData = function(_outSurf, _data, _output_index, _array_index) { surface_set_shader(_outSurf, sh_bw); shader_set_f_map("brightness", _data[1], _data[ 9], inputs[1]); @@ -60,5 +60,5 @@ function Node_BW(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constr _outSurf = channel_apply(_data[0], _outSurf, _data[6]); return _outSurf; - } #endregion + } } \ No newline at end of file diff --git a/scripts/node_threshold/node_threshold.gml b/scripts/node_threshold/node_threshold.gml index c64ab6009..e76073d62 100644 --- a/scripts/node_threshold/node_threshold.gml +++ b/scripts/node_threshold/node_threshold.gml @@ -41,35 +41,61 @@ function Node_Threshold(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) ////////////////////////////////////////////////////////////////////////////////////////////////// + newInput(15, nodeValue_Enum_Scroll("Algorithm", self, 0, [ "Simple", "Adaptive mean" ])); + + newInput(16, nodeValue_Int("Adaptive Radius", self, 4)) + newOutput(0, nodeValue_Output("Surface out", self, VALUE_TYPE.surface, noone)); input_display_list = [ 6, 10, ["Surfaces", true], 0, 4, 5, 11, 12, - ["Brightness", true, 1], 2, 13, 3, + ["Brightness", true, 1], 15, 2, 13, 3,16, ["Alpha", true, 7], 8, 14, 9, ]; attribute_surface_depth(); - static step = function() { #region + static step = function() { __step_mask_modifier(); inputs[2].mappableStep(); inputs[8].mappableStep(); - } #endregion + } - static processData = function(_outSurf, _data, _output_index, _array_index) { #region + static processData = function(_outSurf, _data, _output_index, _array_index) { - surface_set_shader(_outSurf, sh_threshold); - shader_set_i("bright", _data[1]); - shader_set_f_map("brightThreshold", _data[2], _data[13], inputs[2]); - shader_set_f("brightSmooth", _data[3]); + var _surf = _data[0]; + + var _bright = _data[1]; + var _brightThr = _data[2]; + var _brightSmt = _data[3]; + + var _alph = _data[7]; + var _alphThr = _data[8]; + var _alphSmt = _data[9]; + + var _algo = _data[15]; + var _adap_size = _data[16]; + + inputs[16].setVisible(_algo == 1); + + var _shader = sh_threshold; + if(_algo == 1) _shader = sh_threshold_adaptive; + + surface_set_shader(_outSurf, _shader); + shader_set_dim(, _surf); - shader_set_i("alpha", _data[7]); - shader_set_f_map("alphaThreshold", _data[8], _data[14], inputs[8]); - shader_set_f("alphaSmooth", _data[9]); + shader_set_i("bright", _bright); + shader_set_f_map("brightThreshold", _brightThr, _data[13], inputs[2]); + shader_set_f("brightSmooth", _brightSmt); + shader_set_f("adaptiveRadius", _adap_size); + shader_set_f("gaussianCoeff", __gaussian_get_kernel(_adap_size)); - draw_surface_safe(_data[0]); + shader_set_i("alpha", _alph); + shader_set_f_map("alphaThreshold", _alphThr, _data[14], inputs[8]); + shader_set_f("alphaSmooth", _alphSmt); + + draw_surface_safe(_surf); surface_reset_shader(); __process_mask_modifier(_data); @@ -77,5 +103,5 @@ function Node_Threshold(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) _outSurf = channel_apply(_data[0], _outSurf, _data[10]); return _outSurf; - } #endregion + } } diff --git a/shaders/sh_threshold/sh_threshold.fsh b/shaders/sh_threshold/sh_threshold.fsh index c962abb9b..3ca3d8f63 100644 --- a/shaders/sh_threshold/sh_threshold.fsh +++ b/shaders/sh_threshold/sh_threshold.fsh @@ -1,6 +1,3 @@ -// -// Simple passthrough fragment shader -// varying vec2 v_vTexcoord; varying vec4 v_vColour; @@ -34,8 +31,8 @@ void main() { vec4 col = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord ); if(bright == 1) { - float bright = dot(col.rgb, vec3(0.2126, 0.7152, 0.0722)); - col.rgb = vec3(brightSmooth == 0.? _step(bri, bright) : smoothstep(bri - brightSmooth, bri + brightSmooth, bright)); + float cbright = dot(col.rgb, vec3(0.2126, 0.7152, 0.0722)); + col.rgb = vec3(brightSmooth == 0.? _step(bri, cbright) : smoothstep(bri - brightSmooth, bri + brightSmooth, cbright)); } if(alpha == 1) { diff --git a/shaders/sh_threshold/sh_threshold.yy b/shaders/sh_threshold/sh_threshold.yy index d16f61fda..b887a81f9 100644 --- a/shaders/sh_threshold/sh_threshold.yy +++ b/shaders/sh_threshold/sh_threshold.yy @@ -3,8 +3,8 @@ "%Name":"sh_threshold", "name":"sh_threshold", "parent":{ - "name":"colors", - "path":"folders/nodes/data/filter/colors.yy", + "name":"threshold", + "path":"folders/nodes/data/filter/colors/threshold.yy", }, "resourceType":"GMShader", "resourceVersion":"2.0", diff --git a/shaders/sh_threshold_adaptive/sh_threshold_adaptive.fsh b/shaders/sh_threshold_adaptive/sh_threshold_adaptive.fsh new file mode 100644 index 000000000..b5b4bb433 --- /dev/null +++ b/shaders/sh_threshold_adaptive/sh_threshold_adaptive.fsh @@ -0,0 +1,61 @@ +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; +uniform float gaussianCoeff[128]; + +uniform int bright; +uniform vec2 brightThreshold; +uniform int brightThresholdUseSurf; +uniform sampler2D brightThresholdSurf; +uniform float brightSmooth; +uniform float adaptiveRadius; + +uniform int alpha; +uniform vec2 alphaThreshold; +uniform int alphaThresholdUseSurf; +uniform sampler2D alphaThresholdSurf; +uniform float alphaSmooth; + +float _step( in float threshold, in float val ) { return val < threshold? 0. : 1.; } +float getBright( in vec4 c ) { return dot(c.rgb, vec3(0.2126, 0.7152, 0.0722)); } + +void main() { + float bri = brightThreshold.x; + if(brightThresholdUseSurf == 1) { + vec4 _vMap = texture2D( brightThresholdSurf, v_vTexcoord ); + bri = mix(brightThreshold.x, brightThreshold.y, (_vMap.r + _vMap.g + _vMap.b) / 3.); + } + + float alp = alphaThreshold.x; + if(alphaThresholdUseSurf == 1) { + vec4 _vMap = texture2D( alphaThresholdSurf, v_vTexcoord ); + alp = mix(alphaThreshold.x, alphaThreshold.y, (_vMap.r + _vMap.g + _vMap.b) / 3.); + } + + vec4 col = texture2D( gm_BaseTexture, v_vTexcoord ); + vec2 tx = 1. / dimension; + + if(bright == 1) { + float cbright = getBright(col); + float bNeight = 0.; + + for(float j = -adaptiveRadius; j <= adaptiveRadius; j++) + for(float i = -adaptiveRadius; i <= adaptiveRadius; i++) { + float b = getBright(texture2D( gm_BaseTexture, clamp(v_vTexcoord + tx * vec2(i, j), 0., 1.) )); + b *= gaussianCoeff[int(abs(i))] * gaussianCoeff[int(abs(j))]; + bNeight += b; + } + + bNeight -= bri; + + float _res = brightSmooth == 0.? _step(bNeight, cbright) : smoothstep(bNeight - brightSmooth, bNeight + brightSmooth, cbright); + col.rgb = vec3(_res); + } + + if(alpha == 1) { + col.a = alphaSmooth == 0.? _step(alp, col.a) : smoothstep(alp - alphaSmooth, alp + alphaSmooth, col.a); + } + + gl_FragColor = col; +} diff --git a/shaders/sh_threshold_adaptive/sh_threshold_adaptive.vsh b/shaders/sh_threshold_adaptive/sh_threshold_adaptive.vsh new file mode 100644 index 000000000..1a5ddfa49 --- /dev/null +++ b/shaders/sh_threshold_adaptive/sh_threshold_adaptive.vsh @@ -0,0 +1,14 @@ +attribute vec3 in_Position; // (x, y, z) +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; +} \ No newline at end of file diff --git a/shaders/sh_threshold_adaptive/sh_threshold_adaptive.yy b/shaders/sh_threshold_adaptive/sh_threshold_adaptive.yy new file mode 100644 index 000000000..b125ecaa2 --- /dev/null +++ b/shaders/sh_threshold_adaptive/sh_threshold_adaptive.yy @@ -0,0 +1,13 @@ +{ + "$GMShader":"", + "%Name":"sh_threshold_adaptive", + "name":"sh_threshold_adaptive", + "parent":{ + "name":"threshold", + "path":"folders/nodes/data/filter/colors/threshold.yy", + }, + "resourceType":"GMShader", + "resourceVersion":"2.0", + "tags":[], + "type":1, +} \ No newline at end of file