Adjazent | Alan Ross


Webcam Particles

Webcam ParticlesInspired by Andrés fur-experiments and the perlin-particles by Joa this little Webcam idea crossed my mind.
It uses a perlin noise force to position the particles. The particles save their position, have a lifespan and color information.
If you have a webcam you can have a look the Webcam Particles gimmick in action. Enjoy.

The code for the particle effect is fairly simple. First there is the Particle class:

public class Particle
{
  public var next: Particle;

  public var posX: Number;
  public var posY: Number;
  public var velocityX: Number;
  public var velocityY: Number;

  public var livespan: int;
  public var age: int;
  public var color: int;
}

Then the actual force and rendering class. First setup the input and output:

private function init():void
{
  var cam:Camera = Camera.getCamera();
  cam.setMode( 640, 480, 30 );
  _video = new Video( cam.width, cam.height );
  _video.attachCamera( cam );
  _input = new BitmapData( _dim.width, _dim.height, true, 0 );

  _output = new BitmapData( _dim.width, _dim.height, true, 0 );
  _outputBlur = new BitmapData( _dim.width, _dim.height, false, 0 );
  addChild( new Bitmap( _output ) );

  var scale: Number = 4;
  _noise = new BitmapData( _dim.width / scale, _dim.height / scale, false, 0 );
  _force = new BitmapData( _dim.width, _dim.height, true, 0 );
  _scaleMatrix = new Matrix();
  _scaleMatrix.scale( scale, scale );
}

Then the setup the particles:

private function setupParticles(): void
{
  var p: Particle;

  var n: int = NUM_PARTICLES;

  p = _particles = new Particle();

  while( --n > -1)
  {
    p = p.next = new Particle();

    p.posX = Math.random( ) * _dim.width;
    p.posY = Math.random() * _dim.height;

    p.velocityX = Math.random();
    p.velocityY = Math.random();
    p.livespan = Math.random() * 20;
    p.age = 0;
  }
}

The last part is a render-loop / enterframe handler:

private function render( e: Event ): void
{
  _input.draw( _video ); 

  _p0.x += SPEED;
  _p0.y -= SPEED;
  _p1.x -= SPEED;
  _p1.y += SPEED;

  _noise.perlinNoise( 10.0, 10.0, 2, 2, false, true, BitmapDataChannel.GREEN | BitmapDataChannel.BLUE, false, _octaves );
  _force.draw( _noise, _scaleMatrix );

  var particle: Particle = _particles.next;

  do
  {
    force = _force.getPixel( particle.posX, particle.posY );

    ++particle.age;
    if( particle.age > particle.livespan )
    {
      particle.posX = Math.random() * _dim.width;
      particle.posY = Math.random() * _dim.height;
      particle.color = _input.getPixel( particle.posX, particle.posY );
      particle.age = 0;
    }
    else
    {
      if( ( force >> 8 & 0xff ) > 0x80 )
        ++particle.posX;
      else
        --particle.posX;
      if( ( force & 0xff ) > 0x80 )
        ++particle.posY;
      else
        --particle.posY;

      particle.posX += particle.velocityX;
      particle.posY += particle.velocityY;

      a = 0xff * ( particle.age / particle.livespan ) >> 24;
      r = particle.color >> 16;
      g = particle.color >> 8;
      b = particle.color ;

      _outputBlur.setPixel( particle.posX, particle.posY, ( a << 24 | r << 16 | g << 8 | b ) );
    }

    particle = particle.next;

  }
  while( particle );

  _output.copyPixels( _outputBlur, _outputBlur.rect, origin );
  _outputBlur.applyFilter( _outputBlur, _outputBlur.rect, origin, filter );
}

Hope this is of any use to someone…

2 Comments. Leave a comment too

Sweet!


Nice effect.


Trackbacks. Ping Adjazent now.

Popular

Subscribe

Meta