// ## VERTEX SHADER ##
// Author: Jackson Luff
// Name: ParticleUpdate.vert
// Type: Vertex Shader
// Description:
// * This shader is utilized as the
// * standard update loop for the
// * particles. Only difference is
// * that this update loop is on
// * the GPU and not CPU.
#version 410
in layout(location=0) vec3 Position;
in layout(location=1) vec3 Velocity;
in layout(location=2) float Lifetime;
in layout(location=3) float Lifespan;
out vec3 vPosition;
out vec3 vVelocity;
out float vLifetime;
out float vLifespan;
uniform vec3 emitterPosition;
uniform float time;
uniform float deltaTime;
uniform float lifeMin;
uniform float lifeMax;
const float INVERSE_MAX_UINT = 1.0f / 4294967295.0f;
float rand(uint seed, float range)
{
uint i = (seed ^ 12345391u) * 2654435769u;
i ^= (i << 6u) ^ (i >> 26u);
i *= 2654435769u;
i += (i << 5u) ^ (i >> 12u);
return float(range * i) * INVERSE_MAX_UINT;
}
vec3 newVel = vec3(0);
void main()
{
// Get previous velocity
newVel = Velocity;
// Generate seed based on time and vertex ID
uint seed = uint(time * 1000.0) + uint(gl_VertexID);
// Apply trigonometrical positional tracking
vec3 Target = vec3(sin(time), cos(time), tan(time));
vec3 dir = normalize(Target - Position);
newVel += dir;
// Update base information
vPosition = Position + (Velocity * deltaTime);
vVelocity = newVel;
vLifetime = Lifetime + deltaTime;
vLifespan = Lifespan;
// If it's life time is up, reset.
if(vLifetime > vLifespan)
{
//Initialise velocity
vVelocity.x = rand(seed++, 2) - 1;
vVelocity.y = rand(seed++, 2) - 1;
vVelocity.z = rand(seed++, 2) - 1;
vVelocity = normalize(vVelocity);
vPosition = emitterPosition + vec3(sin(time)*0.5, tan(time)*0.5, cos(time)*0.5);
vLifetime = 0;
vLifespan = rand(seed++, lifeMax - lifeMin) + lifeMin;
}
}