93 lines
2.7 KiB
GLSL
93 lines
2.7 KiB
GLSL
#version 430
|
|
|
|
layout(points) in;
|
|
layout(points) out;
|
|
layout(max_vertices = 40) out;
|
|
|
|
// All that we get from vertex shader
|
|
in vec3 position_pass[];
|
|
in vec3 velocity_pass[];
|
|
in vec3 color_pass[];
|
|
in float lifetime_pass[];
|
|
in float size_pass[];
|
|
in int type_pass[];
|
|
|
|
// All that we send further
|
|
out vec3 position_out;
|
|
out vec3 velocity_out;
|
|
out vec3 color_out;
|
|
out float lifetime_out;
|
|
out float size_out;
|
|
out int type_out;
|
|
|
|
uniform vec3 spawn_position; // Position where new particles are spawned
|
|
uniform vec3 spawn_gravity; // Gravity vector for particles - updates velocity of particles
|
|
uniform vec3 spawn_velocity_min; // Velocity of new particle - from min to (min+range)
|
|
uniform vec3 spawn_velocity_range;
|
|
|
|
uniform vec3 spawn_color;
|
|
uniform float spawn_size;
|
|
|
|
uniform float spawn_lifetime_min, spawn_lifetime_range; // Life of new particle - from min to (min+range)
|
|
uniform float time_passed; // Time passed since last frame
|
|
|
|
uniform vec3 random_seed; // Seed number for our random number function
|
|
vec3 local_seed;
|
|
|
|
uniform int number_to_generate; // How many particles will be generated next time, if greater than zero, particles are generated
|
|
|
|
float random_zero_to_one() {
|
|
uint n = floatBitsToUint(local_seed.y * 214013.0 + local_seed.x * 2531011.0 + local_seed.z * 141251.0);
|
|
n = n * (n * n * 15731u + 789221u);
|
|
n = (n >> 9u) | 0x3F800000u;
|
|
|
|
float fRes = 2.0 - uintBitsToFloat(n);
|
|
local_seed = vec3(local_seed.x + 147158.0 * fRes, local_seed.y*fRes + 415161.0 * fRes, local_seed.z + 324154.0*fRes);
|
|
|
|
return fRes;
|
|
}
|
|
|
|
void main() {
|
|
local_seed = random_seed;
|
|
|
|
// gl_Position doesn't matter now, as rendering is discarded
|
|
|
|
position_out = position_pass[0];
|
|
velocity_out = velocity_pass[0];
|
|
|
|
if(type_pass[0] != 0) position_out += velocity_out * time_passed;
|
|
if(type_pass[0] != 0) velocity_out += spawn_gravity * time_passed;
|
|
|
|
color_out = color_pass[0];
|
|
lifetime_out = lifetime_pass[0] - time_passed;
|
|
size_out = size_pass[0];
|
|
type_out = type_pass[0];
|
|
|
|
if(type_out == 0) {
|
|
// This is the emitter particle
|
|
EmitVertex();
|
|
EndPrimitive();
|
|
|
|
for(int i = 0; i < number_to_generate; i++)
|
|
{
|
|
position_out = spawn_position;
|
|
velocity_out = spawn_velocity_min + vec3(
|
|
spawn_velocity_range.x * random_zero_to_one(),
|
|
spawn_velocity_range.y * random_zero_to_one(),
|
|
spawn_velocity_range.z * random_zero_to_one()
|
|
);
|
|
|
|
color_out = spawn_color;
|
|
lifetime_out = spawn_lifetime_min + spawn_lifetime_range * random_zero_to_one();
|
|
size_out = spawn_size;
|
|
type_out = 1;
|
|
|
|
EmitVertex();
|
|
EndPrimitive();
|
|
}
|
|
} else if(lifetime_out > 0.0) {
|
|
// This is a normal particle which is still alive
|
|
EmitVertex();
|
|
EndPrimitive();
|
|
}
|
|
} |