Particle Rope (Godot 4)
Years late into finally porting this over to Godot 4 but here we are and made some small improvements
Demo project has the fully contained scene and is pretty much plug and play but if you instantiate the scene make sure to turn on editable children or no easy editing of the end point in the editor (if you care for that) also the starting point is the particle emitter itself
ALSO VERY IMPORTANT THIS WORKS BEST WITH PARTICLE COUNTS IN POWER OF 2 + 1 DUE TO ME BEING LAZY AND USING FUNKY MATH TO SKIP NEEDING TO PASS THE PARTICLE COUNT TO THE SHADER VIA UNIFORM
More info on how all this generally works on the Godot 3 version here
Shader code
shader_type particles;
uniform vec3 end_point;
uniform vec3 gravity = vec3(0.0, -1.0, 0.0);
uniform float rope_length : hint_range(1.0, 100.0) = 25.0;
uniform float scale : hint_range(0.0, 10.0) = 1.0;
uniform sampler2D scale_curve : source_color, repeat_disable;
uniform vec4 color : source_color = vec4(1.0);
uniform sampler2D color_gradient : source_color, repeat_disable;
float vdc(uint i) {
if (i > 1u) i--;
else return float(i);
i = (i << 16u) | (i >> 16u);
i = ((i & 0x55555555u) << 1u) | ((i & 0xAAAAAAAAu) >> 1u);
i = ((i & 0x33333333u) << 2u) | ((i & 0xCCCCCCCCu) >> 2u);
i = ((i & 0x0F0F0F0Fu) << 4u) | ((i & 0xF0F0F0F0u) >> 4u);
i = ((i & 0x00FF00FFu) << 8u) | ((i & 0xFF00FF00u) >> 8u);
return float(i) * 2.3283064365386963e-10;
}
void process() {
float i = vdc(INDEX);
float new_scale = scale * texture(scale_curve, vec2(i)).r;
TRANSFORM[0].x = new_scale;
TRANSFORM[1].y = new_scale;
TRANSFORM[2].z = new_scale;
TRANSFORM[3].xyz = mix(EMISSION_TRANSFORM[3].xyz, end_point, i) - gravity * (i * i - i) * 4.0 * max((rope_length - distance(EMISSION_TRANSFORM[3].xyz, end_point)) * 0.5, 0.0);
COLOR = color * texture(color_gradient, vec2(i));
}
