Particle2D that emits with even (as opposed to random) spread

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By someseven

Basically subj. It’s almost a duplicate of this question
But the accepted solution emits particles in random directions.

I also wanted to do this so I tried converting the particle material to a particle shader and editing the shader. I haven’t done anything with shaders before so this might not be proper but it is what I have so far.

In order to spread the particles out evenly the shader would have to know the amount of particles. This doesn’t seem to be available in the vertex buffer (?) so I resorted to passing the shader a uniform value

uniform float initial_particle_amount; // added this

but I have to set that value manually or with a script.
Then I replaced the line

float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;


float angle1_rad = (float(INDEX) * (spread_rad / (initial_particle_amount / 2.0)));

and that emitted the particles in and even spread.

I noticed there is a initial_angle_random value but I don’t understand what it does. Ideally we would be able to set a value between 0 and 1 to control the “randomness” of the particle spread.

Sansduke | 2021-11-25 20:22

:bust_in_silhouette: Reply From: Inces

You can convert particle material to particle shader, and there override direction/velocity code. You will have to write similar function to what You would do in Godot - iterate through angles of circle and assign direction within chosen intervals. You will have to learn shader language tho. Try to come up with something and post Your result here, I will try to correct You.

Thanks! I already tried it with shaders but couldn’t find a way to get the particle’s number then (since explosiveness may be 100%). Just needed to RTFM. :confused: There are two. NUMBER and INDEX. So, replace

float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;


float angle1_rad = fract(float(NUMBER) * angle_step) * spread_rad;

Where angle_step is a uniform float. And this would be the first time I successfully tinkered with shaders.

For anyone finding this question later, TFM is here: Particle shaders — Godot Engine (stable) documentation in English

someseven | 2021-11-25 02:51

Inspired by this answer, here is a simplified version of the entire particles shader for godot 4.0

shader_type particles;

uniform float angle_step;
uniform float initial_velocity;

void start(){
    float degree_to_rad = PI / 180.0;

	    float angle1_rad = float(INDEX) * angle_step * degree_to_rad;
	    vec3 rot = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);
	    VELOCITY = rot * initial_velocity;
	    TRANSFORM[3] = vec4(0);

note that this will not subject to the particle node’s transformation, and the first particle emit will always move to the right x axis

Geazas | 2023-06-10 15:56