From eef883be976a2ab590873103858fef3b7a9a50df Mon Sep 17 00:00:00 2001 From: Jules Fouchy Date: Mon, 16 Oct 2023 20:09:00 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9F=A6=20[Nodes]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Color Ramp.clbnode.presets.json | 166 ++++++++++++++++++ Nodes/Force Field/Coulomb.clbnode | 24 +++ .../Force Field Renderer 2.clbnode | 91 ++++++++++ .../Force Field/Force Field Renderer.clbnode | 25 +++ Nodes/Force Field/_category_config.json | 6 + 5 files changed, 312 insertions(+) create mode 100644 Nodes/Force Field/Coulomb.clbnode create mode 100644 Nodes/Force Field/Force Field Renderer 2.clbnode create mode 100644 Nodes/Force Field/Force Field Renderer.clbnode create mode 100644 Nodes/Force Field/_category_config.json diff --git a/Nodes/11 Image Modifier (Post Process)/Color Ramp.clbnode.presets.json b/Nodes/11 Image Modifier (Post Process)/Color Ramp.clbnode.presets.json index be0211ce..d8e5899f 100644 --- a/Nodes/11 Image Modifier (Post Process)/Color Ramp.clbnode.presets.json +++ b/Nodes/11 Image Modifier (Post Process)/Color Ramp.clbnode.presets.json @@ -365,6 +365,172 @@ } ] } + }, + { + "first": "5177efec-9318-4caf-9c4a-1d8dc68e884b", + "second": { + "Name": "Pastel", + "Values": [ + { + "index": 15, + "data": { + "Name": "Color Gradient", + "Value": { + "Gradient": [ + { + "Mark position": { + "Relative position": 0.0 + }, + "Mark color": { + "x": 0.002346101449802518, + "y": 0.0, + "z": 0.35913366079330447, + "w": 1.0 + } + }, + { + "Mark position": { + "Relative position": 0.20000000298023225 + }, + "Mark color": { + "x": 1.0, + "y": 0.7019608020782471, + "z": 0.729411780834198, + "w": 1.0 + } + }, + { + "Mark position": { + "Relative position": 0.4000000059604645 + }, + "Mark color": { + "x": 0.729411780834198, + "y": 0.8823529481887817, + "z": 1.0, + "w": 1.0 + } + }, + { + "Mark position": { + "Relative position": 0.6000000238418579 + }, + "Mark color": { + "x": 0.729411780834198, + "y": 1.0, + "z": 0.7882353067398071, + "w": 1.0 + } + }, + { + "Mark position": { + "Relative position": 0.800000011920929 + }, + "Mark color": { + "x": 1.0, + "y": 0.8745098114013672, + "z": 0.729411780834198, + "w": 1.0 + } + }, + { + "Mark position": { + "Relative position": 1.0 + }, + "Mark color": { + "x": 1.0, + "y": 1.0, + "z": 0.729411780834198, + "w": 1.0 + } + } + ], + "Wrap Mode": 0, + "Interpolation Mode": 2 + }, + "Metadata": { + "Is HDR": false, + "Randomize new marks' colors": true + }, + "Default Value": { + "Gradient": [ + { + "Mark position": { + "Relative position": 0.0 + }, + "Mark color": { + "x": 0.002346101449802518, + "y": 0.0, + "z": 0.35913366079330447, + "w": 1.0 + } + }, + { + "Mark position": { + "Relative position": 0.20000000298023225 + }, + "Mark color": { + "x": 1.0, + "y": 0.7019608020782471, + "z": 0.729411780834198, + "w": 1.0 + } + }, + { + "Mark position": { + "Relative position": 0.4000000059604645 + }, + "Mark color": { + "x": 0.729411780834198, + "y": 0.8823529481887817, + "z": 1.0, + "w": 1.0 + } + }, + { + "Mark position": { + "Relative position": 0.6000000238418579 + }, + "Mark color": { + "x": 0.729411780834198, + "y": 1.0, + "z": 0.7882353067398071, + "w": 1.0 + } + }, + { + "Mark position": { + "Relative position": 0.800000011920929 + }, + "Mark color": { + "x": 1.0, + "y": 0.8745098114013672, + "z": 0.729411780834198, + "w": 1.0 + } + }, + { + "Mark position": { + "Relative position": 1.0 + }, + "Mark color": { + "x": 1.0, + "y": 1.0, + "z": 0.729411780834198, + "w": 1.0 + } + } + ], + "Wrap Mode": 0, + "Interpolation Mode": 2 + }, + "Default Metadata": { + "Is HDR": false, + "Randomize new marks' colors": true + } + } + } + ] + } } ] } diff --git a/Nodes/Force Field/Coulomb.clbnode b/Nodes/Force Field/Coulomb.clbnode new file mode 100644 index 00000000..5932077b --- /dev/null +++ b/Nodes/Force Field/Coulomb.clbnode @@ -0,0 +1,24 @@ +// To learn how to write nodes, see https://coollab-art.com/Tutorials/Writing%20Nodes/Intro + +INPUT float 'Strength'; +INPUT Point2D 'Charge 1'; +INPUT float 'Charge 1 Strength'; +INPUT Point2D 'Charge 2'; +INPUT float 'Charge 2 Strength'; +INPUT Point2D 'Charge 3'; +INPUT float 'Charge 3 Strength'; + +vec2 force(vec2 pos, vec2 charge_pos, float charge_strength) +{ + return 'Strength' * charge_strength / dot(pos - charge_pos, pos - charge_pos) * normalize(pos - charge_pos); +} + +vec2 main(UV Position) +{ + return vec2(0.) + + force(Position, 'Charge 1', 'Charge 1 Strength') + + force(Position, 'Charge 2', 'Charge 2 Strength') + + force(Position, 'Charge 3', 'Charge 3 Strength') + // + ; +} \ No newline at end of file diff --git a/Nodes/Force Field/Force Field Renderer 2.clbnode b/Nodes/Force Field/Force Field Renderer 2.clbnode new file mode 100644 index 00000000..777e4f3e --- /dev/null +++ b/Nodes/Force Field/Force Field Renderer 2.clbnode @@ -0,0 +1,91 @@ +// To learn how to write nodes, see https://coollab-art.com/Tutorials/Writing%20Nodes/Intro + +INPUT float 'Thickness'; +INPUT float 'Blur'; +INPUT int 'Lines'; +INPUT Point2D 'Pos 1'; +INPUT Point2D 'Pos 2'; +INPUT float 'Charge 1'; +INPUT float 'Charge 2'; +INPUT float 'Seed'; +INPUT int 'Max steps'; +INPUT float 'h'; + +// https://www.shadertoy.com/view/XsSyzc + +vec2 E(vec2 p, vec2 q, vec2 q1, vec2 q2) +{ + return normalize(q.x * (p - q1) / pow(length(q1 - p), 3.) + q.y * (p - q2) / pow(length(q2 - p), 3.)); +} + +float line(vec2 p, vec2 a, vec2 b) +{ + // vec2 dir = normalize(p2 - p1); + // mat2 inv = mat2(dir.x, -dir.y, dir.y, dir.x); + // uv = inv * (uv - p1); + // p2 = inv * (p2 - p1); + // return float(abs(uv.y) < 'Thickness' && 0. < uv.x && uv.x < p2.x); + + vec2 ba = b - a; + vec2 pa = p - a; + float h = clamp(dot(pa, ba) / dot(ba, ba), 0., 1.); + return smoothstep(+'Blur', -'Blur', length(pa - h * ba) - 'Thickness'); +} + +vec2 RK4(vec2 p, vec2 q, vec2 q1, vec2 q2) +{ + vec2 k1 = E(p, q, q1, q2); + vec2 k2 = E(p + 0.5 * 'h' * k1, q, q1, q2); + vec2 k3 = E(p + 0.5 * 'h' * k2, q, q1, q2); + vec2 k4 = E(p + 'h' * k3, q, q1, q2); + return 'h' / 3. * (0.5 * k1 + k2 + k3 + 0.5 * k4); +} + +vec2 integrate(float O, vec2 p, vec2 q, vec2 q1, vec2 q2, vec2 start, vec2 end) +{ + O += line(p, mix(q1, q2, float(length(q1 - start) > 'h' * 1.001)), start); + vec2 pn; + vec2 po = start; + for (int i = 0; i < 'Max steps'; i++) + { + pn = po + RK4(po, q, q1, q2); + O += line(p, po, pn); + po = pn; + if (length(end - po) < 'h') + { + O += line(p, po, end); + return vec2(O, -1.); + } + if (/* abs(po.x) > iResolution.x / iResolution.y || */ abs(po.y) > 1.0) + return vec2(O, +1.); + } + return vec2(O, +1.); +} + +float main(UV uv) +{ + float O = 0.; + float prevO = 0.; + vec2 q1 = 'Pos 1'; + vec2 q2 = 'Pos 2'; + vec2 q = vec2('Charge 1', 'Charge 2'); + float rand = 0.; + for (float o = 0.; o < TAU; o += TAU / 'Lines') + { + float angle = TAU / (2. * 'Lines') + o; + vec2 os = vec2(cos(angle), sin(angle)) * 0.01; + vec2 res = integrate(O, uv, q, q1, q2, q1 + os, q2); + O = res.x; + if (res.y > 0. && abs(q.y) > 0.) + { + res = integrate(O, uv, q.y / abs(q.y) * q, q1, q2, q2 + mat2(-1, 0, 0, 1) * os, q1); + O = res.x; + } + if (O != prevO) + { + rand = hash_0_to_1_2D_to_1D(vec2(o, 'Seed')); + prevO = O; + } + } + return rand; +} \ No newline at end of file diff --git a/Nodes/Force Field/Force Field Renderer.clbnode b/Nodes/Force Field/Force Field Renderer.clbnode new file mode 100644 index 00000000..623d2b33 --- /dev/null +++ b/Nodes/Force Field/Force Field Renderer.clbnode @@ -0,0 +1,25 @@ +// To learn how to write nodes, see https://coollab-art.com/Tutorials/Writing%20Nodes/Intro + +INPUT float 'Grid Size'; +INPUT float 'Arrow Thickness'; +INPUT float 'Period'; +INPUT float 'Color Min'; +INPUT float 'Color Max'; +INPUT UV->vec2 'Force Field'; + +float main(UV uv) +{ + vec2 gid = floor(uv * 'Grid Size') / 'Grid Size'; + vec2 guv = fract(uv * 'Grid Size') * 2. - 1.; + vec2 force = 'Force Field'(gid); + // force = vec2(-force.y, force.x); + float angle = atan(force.y, force.x); + guv = rotation_2D(angle) * guv; + return mix('Color Min', 'Color Max', sin(length(force) * 'Period') * 0.5 + 0.5) + * step(-1., guv.x) + * (1. - step(1., guv.x)) + * step(-'Arrow Thickness', guv.y) + * (1. - step(+'Arrow Thickness', guv.y)) + // + ; +} \ No newline at end of file diff --git a/Nodes/Force Field/_category_config.json b/Nodes/Force Field/_category_config.json new file mode 100644 index 00000000..e4102897 --- /dev/null +++ b/Nodes/Force Field/_category_config.json @@ -0,0 +1,6 @@ +{ + "value0": { + "Color": 5, + "Number of main input pins": 1 + } +} \ No newline at end of file