Particle Rope

Something I originally made in garry’s mod and figured I’d port it over to godot

I recommend taking a look at the demo project since this works best with a simple tool script to more easily move the start and end points in the editor and to keep the uniform amount synced with your actual particle amount

If you need any help or know of ways to improve this then fell free to contact me on discord

TᴜƦᴛʟᴇ#7591

INSTRUCTIONS

  1. Create Particles node and make sure explosiveness is set to 1
  2. Make a new shader material with the shader code below
  3. Make sure the uniform amount matches the amount on the Particles node
  4. Configure the other uniforms as you like
  5. Set Use As Albedo to true in the Vertex Color tab for your draw passes material

THINGS TO KNOW ABOUT THE DEMO PROJECT

If you create multiple instances of the rope scene make sure they all have their Process Material and Draw Passes Material made unique or you’ll end up like me wondering why all the ropes just merged into one or material changes end up messing up all the other rope particles

I wouldn’t mess with the transform of the Particles node unless you know what you’re doing

When you do make an instance of the rope scene make it local to have an easier time with moving the start and end node

WHAT THE UNIFORMS DOIN?

Amount: Particle shaders don’t have access to the amount of particles being emitted so this is needed

Max Rope Distance: The distance between the start and end point needed to flatten the rope curve

Scale: The scale of each particle

Start: Starting position of the rope

End: Ending position of the rope

Curve Direction: The direction the points will move towards

Color: Main color of all the particles can be used without setting a color gradient texture

Color Gradient: The gradient texture used to color the particles differently from each other

Shader code
shader_type particles;

uniform int amount : hint_range(1, 1000) = 8;

uniform float max_rope_distance : hint_range(1.0, 1000.0) = 20.0;
uniform float scale : hint_range(0.0, 10.0) = 1.0;

uniform vec3 start = vec3(-5.0, 5.0, 0.0);
uniform vec3 end = vec3(5.0, 5.0, 0.0);
uniform vec3 curve_direction = vec3(0.0, -1.0, 0.0);

uniform vec4 color : hint_color = vec4(1.0);

uniform sampler2D color_gradient : hint_white;

void vertex() {
	float new_index = float(INDEX) / float(amount - 1);
	
	TRANSFORM[0].x = scale;
	TRANSFORM[1].y = scale;
	TRANSFORM[2].z = scale;
	TRANSFORM[3].xyz = mix(start, end, new_index) - curve_direction * (new_index * new_index - new_index) * 4.0 * max((max_rope_distance - distance(start, end)) * 0.5, 0.0);
	
	COLOR.rgb = texture(color_gradient, vec2(new_index, 0.0)).rgb * color.rgb;
}
Tags
particles, Rope
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from Turtle

Rainbow

Cube Mesh Glow Outline

Related shaders

Spatial particle shader

Particle Process V2

Wandering Clipmap – Foliage Particle Process

Subscribe
Notify of
guest

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Joshua Morris
Joshua Morris
8 months ago

For use with Godot 4

shader_type particles;


uniform int amount : hint_range(1, 1000) = 8;


uniform float max_rope_distance : hint_range(1.0, 1000.0) = 20.0;
uniform float scale : hint_range(0.0, 10.0) = 1.0;


uniform vec3 start = vec3(-5.0, 5.0, 0.0);
uniform vec3 end = vec3(5.0, 5.0, 0.0);
uniform vec3 curve_direction = vec3(0.0, -1.0, 0.0);


uniform vec4 color : source_color = vec4(1.0);


uniform sampler2D color_gradient : hint_default_white;


void process() {
	float new_index = float(INDEX) / float(amount - 1);
	
	TRANSFORM[0].x = scale;
	TRANSFORM[1].y = scale;
	TRANSFORM[2].z = scale;
	TRANSFORM[3].xyz = mix(start, end, new_index) - curve_direction * (new_index * new_index - new_index) * 4.0 * max((max_rope_distance - distance(start, end)) * 0.5, 0.0);
	
	COLOR.rgb = texture(color_gradient, vec2(new_index, 0.0)).rgb * color.rgb;
}
Joshua Morris
Joshua Morris
8 months ago

Awesome, shader by the way! Thank you for sharing!