mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
73 lines
2.9 KiB
GLSL
73 lines
2.9 KiB
GLSL
uniform float lifespan = 1.0; // seconds
|
|
uniform float speed = 0.1; // m/s
|
|
uniform float speedSpread = 0.25;
|
|
uniform float mass = 1.0;
|
|
|
|
const float G = 6.67e-11;
|
|
|
|
// prop0: xyz: position, w: age
|
|
// prop1: xyz: velocity, w: prevUpdateTime
|
|
// prop2: xyz: prevVelocity
|
|
|
|
vec3 initPosition(const int particleID) {
|
|
return 0.5 * (vec3(hifi_hash(particleID + iGlobalTime),
|
|
hifi_hash(particleID + iGlobalTime + 1.0),
|
|
hifi_hash(particleID + iGlobalTime + 2.0)) - 0.5);
|
|
}
|
|
|
|
mat3 rotationMatrix(vec3 axis, float angle) {
|
|
float s = sin(angle);
|
|
float c = cos(angle);
|
|
float oc = 1.0 - c;
|
|
|
|
return mat3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
|
|
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
|
|
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c);
|
|
}
|
|
|
|
vec3 initVelocity(const int particleID, const vec3 position) {
|
|
const float particleSpeed = speed * ((1.0 - speedSpread) + speedSpread * hifi_hash(particleID + iGlobalTime + 3.0));
|
|
vec3 r = normalize(iWorldPosition - position);
|
|
float angle = 2.0 * 3.14159 * hifi_hash(particleID + iGlobalTime + 4.0);
|
|
return particleSpeed * rotationMatrix(r, angle) * cross(r, vec3(0, 1, 0));
|
|
}
|
|
|
|
void updateParticleProps(const int particleID, inout ParticleUpdateProps particleProps) {
|
|
// First draw
|
|
if (particleProps.prop1.w < 0.00001) {
|
|
particleProps.prop0.xyz = iWorldOrientation * (initPosition(particleID) * iWorldScale) + iWorldPosition;
|
|
particleProps.prop0.w = -lifespan * hifi_hash(particleID + iGlobalTime + 3.0);
|
|
particleProps.prop1.xyz = initVelocity(particleID, particleProps.prop0.xyz);
|
|
particleProps.prop1.w = iGlobalTime;
|
|
particleProps.prop2.xyz = particleProps.prop1.xyz;
|
|
return;
|
|
}
|
|
|
|
// Particle expired
|
|
if (particleProps.prop0.w >= lifespan) {
|
|
particleProps.prop0.xyz = iWorldOrientation * (initPosition(particleID) * iWorldScale) + iWorldPosition;
|
|
particleProps.prop0.w = 0.0;
|
|
particleProps.prop1.xyz = initVelocity(particleID, particleProps.prop0.xyz);
|
|
particleProps.prop1.w = iGlobalTime;
|
|
particleProps.prop2.xyz = particleProps.prop1.xyz;
|
|
return;
|
|
}
|
|
|
|
float dt = 0.01666666666;//max(0.0, iGlobalTime - particleProps.prop1.w);
|
|
particleProps.prop2.xyz = particleProps.prop1.xyz;
|
|
if (particleProps.prop0.w >= 0.0) {
|
|
// gravitational acceleration
|
|
vec3 r = iWorldPosition - particleProps.prop0.xyz;
|
|
vec3 g = (G * mass / max(0.01, dot(r, r))) * r;
|
|
|
|
// position
|
|
particleProps.prop0.xyz += particleProps.prop1.xyz * dt + (0.5 * dt * dt) * g;
|
|
// velocity
|
|
particleProps.prop1.xyz += g * dt;
|
|
}
|
|
|
|
// age
|
|
particleProps.prop0.w += dt;
|
|
// prevUpdateTime
|
|
particleProps.prop1.w = iGlobalTime;
|
|
}
|