Topical Workshop on Electronics for Particle Physics Paris, September 23rd, 2009
Paris Master Class 2011 - 06 Gpu Particle System
-
Upload
wolfgang-engel -
Category
Engineering
-
view
163 -
download
5
Transcript of Paris Master Class 2011 - 06 Gpu Particle System
Agenda
• Why GPU Particle System (PS)?• Difference between a Stateless / State-
preserving PS• Implementation of a State-preserving PS
Why GPU Particles?
• CPU Particles: – transfer bandwidth of particle data CPU -> GPU ==
bottleneck– CPU not fast enough
• GPU Particles [Latta]: – Data is generated on the GPU and kept on the
GPUminimize CPU <-> GPU interaction
– Challenges: how to play sound ….
Stateless / State-Preserving PS
• Stateless: data computed from birth to death by closed-form function
p is the computed particle positionp0 is the initial position
v0 is the initial velocity
t is the current time
• Does not store current position or other attributes-> can hardly react to a change of the environment
• First-gen programmable GPU -> 99% of all particle systems used in games
• Ideal for small and simple effects without environment interaction e.g. weapon, splash, sparks of a collision
Stateless / State-Preserving PS
• State-preserving: numerical, iterative integration method – Compute particle data every frame by comparing
with the data from the previous frame• Integral of acceleration over time gives you velocity• Integral of velocity over time gives you position
– Based on environmental changes or other changes
• More flexible -> Next-Gen
State-Preserving PS
• Agenda– Particle Data Storage– Process birth and death– Update Velocities– Update Positions– (Optional) Sort for alpha blending or other
reasons
State-Preserving PS
• Particle Data Storage• Most important data is position and velocity• There is also orientation, size, color, opacity• Stored each in render targets (several values packed up in
16-bit or 32-bit fp render target channels)-> each texture is conceptually treated as a 1D array; texture coordinates representing array indices-> textures are 2D
• Blit into render target• Data need to be double-buffered because a texture can’t
be read and write to at the same time
State-Preserving PS
• Process birth and death– Birth and death are handled on the GPU -> no CPU
interaction– A time variable decides on the death and re-birth of
the particle– In case of a GPU Particle system there is re-birth
happening -> the particles just can’t remember their previous life
– In other words the slot in the texture is re-used over and over again
State-Preserving PS
• Process birth and deathpos.w += frameTime;
// if the particle exists since more than 4 seconds let it die and re-birth at the same time with some starting valuesif (pos.w >= 4.0){
// Restart animationdir.xyz = sprinkleDir;pos.xyz = float3(0, -235, 0);pos.w -= 4.0;
} else {
// run a cool physics simulation here}
State-Preserving PS
• Update Velocities– Several velocity operations possible– Global forces: gravity, wind– Local forces (all are based on a fall off with
distance): • Attraction • Repulsion• Velocity dampening / un-dampening• Collision response
State-Preserving PS
• Update Velocities• Complex local forces can be mapped with a 2D or 3D
texture containing vector data -> called flow field texture• Sampled flow vector vfl can be used with Stoke’s law of a
drag force Fflow on a sphere
• Where η is the flow viscosity, r the radius of the sphere (in our case the particle) and v the velocity vector
State-Preserving PS
• Update Velocities• All global and local forces are then accumulated into a single force vector• Convert force to acceleration -> Newton physics
where
a is the acceleration vector
F the accumulated force
m the particle’s mass
• Velocity is then updated from acceleration with simple Euler integration
where
v is the current velocity,
v is the previous velocity
∆t the time step
• Update Velocitiespos.w += frameTime;
if (pos.w >= 4.0)
{
// initialization
} else {
// Gravity
// rough approx. of Newton physics
// a = F / m
// here m is 1.0
// Update position ~ Euler integration
// v = vprev + a * deltaTime
dir.y -= 500.0 * frameTime;
// Update position
// collision handling comes here
}
State-Preserving PS
• Update Velocities– Dampening
• special case of Stoke’s law of drag force on a sphere
– With vflow == 1.0
• Or just
r – distancee – small epsilon to prevent divide by 0
• Or just
// dampening simplified
dir.xyz -= (dir.xyz * frameTime2 * 0.4f);
– Un-dampening: imitate self-propelled objects like a bee swarm
State-Preserving PS
• Update Velocities– Collision [Sims]– Split velocity (relative to collider) into normal vn ad
tagential vt component
vn = (v.n)n
vt = v - vnn is the normal of the collider == plane normal/normal map
v is the velocity computed so far
vn is the normal component of velocity
vt is the tangential vector
State-Preserving PS
• Update Velocities– Collision [Sims]
New velocity is then
dynamic friction μ reduces the tangential component
resilience Є scales the reflected normal component
vn = collisionPlane.xyz * dot(collisionPlane.xyz, velocity.xyz);
vt = velocity.xyz – vn;
velocity.xyz = (1 – u) * vt – e*vn;
State-Preserving PS
• Update Velocities– Collision [Sims]– Challenges• dynamic friction μ might approach zero
-> don’t apply friction slow-down if velocity is smaller than threshold
State-Preserving PS
• Update Velocities– Particles caught in the collider• Calculate distance twice for previous and current frame• Create line segment• Figure out the contact point• Set the new position to the contact point
float4 collisionPlane = collisionPlanes[collisionPlaneIdx];
float startDist = dot(lastPosition.xyz, collisionPlane.xyz) - collisionPlane.w;
float endDist = dot(position.xyz, collisionPlane.xyz) - collisionPlane.w;
…
//
float3 lineSegment = (position - lastPosition);
float frontbackRatio = abs(startDist) / (abs(startDist) + abs(endDist));
float3 contactPoint = lastPosition + (frontbackRatio * lineSegment);
State-Preserving PS
• Update Velocities– Other collision
• Terrain: height map -> generate normal from height map• Complex collisions -> cube collision map store depth and normals
in a cube map
State-Preserving PS
• Update Position– Integral of velocity over time gives you position
-> Euler Integration again for position
if (pos.w >= 4.0){
// Restart animation
dir.xyz = sprinkleDir;
pos.xyz = float3(0, -235, 0);
pos.w -= 4.0;
} else {
// Gravity
dir.y -= 500.0 * frameTime;
// Update position
// p = p + v * deltaTime
pos.xyz += frameTime * dir;
}
State-Preserving PS
• Sorting – Sort per-particle
• For alpha blending– Ignore if possible– Use Order-Independent Transparency– Sort on the GPU -> expensive see [Latta]
• Any other reason to sort per-particle -> probably not
– Sort per-emitter • Sort emitters with certain properties like lights, lights and
shadows and render them together• Sort on the CPU -> send down new index points into the
render targets -> next to free on the GPU
State-Preserving PS
• Alternatives to Euler Integration– Verlet Integration see [Latta] -> save the velocity
buffer – Runge Kutta RK4 [Fiedler]
State-Preserving PS
References
• [Latta] Lutz Latta, http://www.2ld.de/• [Fiedler] Glenn Fiedler
http://gafferongames.com/game-physics/integration-basics/
• [Sims] Sims, Karl; Particle Animation and Rendering Using Data Parallel Computation, in SIGGRAPH Proceedings 1990