среда, 16 мая 2012 г.

Stateless particle system on GPU


Hello. I want to show you how to make particle system that runs entirely on GPU. And as it runs on graphics card it's blazingly fast! On my modern card I get 1.7 million particles on 60 FPS! Adding more particles causes stage3D exception - there's a limitation on triangles number. The main disadvantage of such system is that it's stateless. That means that you only have 'start' data for each particle and you can't save it as data changes. The particle moves according to some rule that you pass to GPU. For example, remember school physics and formula of free falling body position (formula from wikipedia):


As you can see, if you know time, you can calculate current position of the body. You got the idea.

Here's a demo with single particle:

                   

Here the steps of simulation:

-pass vertices to the GPU. I use 4 vertices and 2 triangles.
-pass particles start positions to the GPU. Bad news that you need to pass such data per vertex, not per particle. It leads to data duplication and memory use.
-pass colors. Per vertex.
-pass additional data such as travel distance and duration of travel. Again, you need to duplicate data.
-on every update pass current time. According to that time shader computes current position simply as end position minus start position multiplied by time delta (from 0 to one).

Vertex shader:
 
var vertexShaderString:String =
'add vt0 va0.xy va1.xy\n' + // va0 - local vertex position, va1 - global vertex position
'mov vt0.zw vc4.xx\n' + // fill data with 1
'div vt1.x vc4.y va3.z\n' + // vc4.y - getTimer(), va3.z - travel duration
'frc vt1.x vt1.x\n' + // get value from 0 to 1
'mul vt1.xy va3.xy vt1.xx\n' + // va3.xy - travel length on x and y axes
'add vt0.xy vt0.xy vt1.xy\n' +
'm44 op vt0 vc0\n' +
'mov v0 va2'; // pass color

Fragment shader:
 
var fragmentShaderString:String = 
'mov oc v0';

Here's a demo with tons of particles (add more with button):


                 


Комментариев нет:

Отправить комментарий