Monthly Archives: July 2009

Perlin Outlines

Actionscript:
  1. [SWF(width = 600, height=600, backgroundColor=0xCCCCCC, frameRate=24)]
  2. var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight, false, 0x000000);
  3. var blur:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight, false, 0x000000);
  4. addChild(new Bitmap(canvas, "auto", true));
  5.  
  6. var w:int = canvas.width
  7. var hw:int = w / 2;
  8. var size:int = w * w;
  9. var seed:Number = Math.random()*100;
  10. var pnt:Point = new Point();
  11. var dy:Number = 0, dx:Number = 0;
  12. var blr:BlurFilter = new BlurFilter(10,10,1);
  13. addEventListener(Event.ENTER_FRAME, onLoop);
  14. function onLoop(evt:Event):void {
  15.    
  16.     dx += (mouseX - dx) / 4;
  17.     dy += (mouseY - dy) / 4;
  18.     canvas.lock();
  19.     canvas.perlinNoise(hw,hw,2,seed,false, false, 1, true, [new Point(dx, dy), new Point(-dx, -dy)]);
  20.     var pix:Vector.<uint> = canvas.getVector(canvas.rect);
  21.     for (var i:int = 0; i<size; i++){
  22.         var col:uint = 255 - pix[i] <<4 & 0x00FF00;
  23.         pix[i] = col <<8 | col | col>> 8;
  24.     }
  25.     canvas.setVector(canvas.rect, pix);
  26.     blur.copyPixels(canvas, canvas.rect, pnt);
  27.     blur.applyFilter(blur, blur.rect, pnt, blr);
  28.     canvas.draw(blur, null, null, BlendMode.DIFFERENCE);
  29.     canvas.draw(canvas, null, null, BlendMode.INVERT);
  30.     canvas.unlock();
  31. }

This is actually an optimized variation on some recent posts that made use of perlin noise. You can get a wide range of effects by changing just the BlendMode values alone.... I particularly like this combination of BlendModes because it reminds me a bit of a terrain map...

Have a look at the swf...

Posted in BitmapData, Vector, pixel manipulation | Tagged , , | Leave a comment

Parallax fp10

Actionscript:
  1. [SWF(backgroundColor=0x000000, width = 800, height = 600)]
  2.  
  3. // this is a trick to keep the 3D texture quality up...
  4. // try setting it right off the bat and you'll notice that the
  5. // Shapes look pixilated
  6. setTimeout(function():void{ stage.quality="low"}, 500);
  7.  
  8. var matrix:Matrix = new Matrix();
  9. matrix.createGradientBox(600, 600, 0, -450, -450);
  10.  
  11. var boxNum:int = 30;
  12. var boxes:Array = [];
  13. for (var i:int = 0; i<boxNum; i++) boxes[i] = makeBox();
  14.  
  15. var dx:Number = 0, dy:Number = 0;
  16. onLoop();
  17. addEventListener(Event.ENTER_FRAME, onLoop);
  18.  
  19. function onLoop(evt:Event=null):void {
  20.     dx += (mouseX - dx) / 4;
  21.     dy += (mouseY - dy) / 4;
  22.     for (var i:int = 0; i<boxNum; i++){
  23.         var box:Shape = boxes[i];
  24.         box.z = 400 - i * 20;
  25.         box.x = dx;
  26.         box.y = dy;
  27.         box.rotation = i + getTimer() / 10;
  28.     }
  29. }
  30.  
  31. function makeBox():Shape{
  32.     var box:Shape = Shape(addChild(new Shape()));
  33.     box.x = stage.stageWidth/2;
  34.     box.y = stage.stageHeight/2;
  35.     box.z = 1;
  36.     with (box.graphics){
  37.          beginGradientFill(GradientType.RADIAL, [0xFFFFFF, 0x333333], [1,1], [0, 255], matrix, SpreadMethod.PAD);
  38.         drawRect(-100, -100, 200, 200);
  39.         drawRect(-70, -70, 140, 140);
  40.     }
  41.     return box;
  42. }

This snippet draws 30 gradient box shapes, gives them different z values and then moves them based on the mouse. This technique is good if you just want a few layers of parallax motion - I got carried away and you'll notice that if you add more boxes it begins to slow down pretty quick.


Have a look at the swf....



I first used this technique for this small interactive drawing...

Something interesting I noticed about fp10 3D DisplayObjects is that if you set the stage.quality to low right off the bat, the display objects look pixelated... but if you wait a few milliseconds, you end up with less pixelation and you still get a speed boost from the low quality - I think it must have something to do with the way the 3D textures are handled by the player...

Tomorrow I think I'll post a version of this that uses IGraphicsData and Utils.projectVectors()... should be a huge speed boost...

Posted in 3D, motion | Tagged , , | 1 Comment

Another Perlin Texture

Actionscript:
  1. var canvas:BitmapData = new BitmapData(1200,1200,false, 0x000000);
  2. addChild(new Bitmap(canvas));
  3.  
  4. scaleX = scaleY = 0.5;
  5. var w:int = canvas.width
  6. var hw:int = w / 2;
  7. var hhw:int = hw / 2;
  8. var size:int = canvas.width * canvas.width;
  9.  
  10. canvas.perlinNoise(hhw,hhw,1,Math.random()*100,false, false, 1, true);
  11.  
  12. for (var i:int = 0; i<size; i++){
  13.     var xp:int = i % w;
  14.     var yp:int = int(i / w);
  15.     var col:uint =  canvas.getPixel(xp, yp) / (-20|i+xp)>> 8 & 0xFF
  16.     canvas.setPixel(xp, yp, col <<16 | col <<8 | col);
  17. }
  18.  
  19. canvas.applyFilter(canvas, canvas.rect, new Point(0,0), new BlurFilter(4,4,1));
  20. var blur:BitmapData = canvas.clone();
  21. blur.applyFilter(blur, blur.rect, new Point(0,0), new BlurFilter(10,10,1));
  22.  
  23. canvas.draw(blur, null, null, BlendMode.DARKEN);

This is a variation on yesterdays post. I think it's time to optimize this and see how it does in real time...

Here is what this snippet will draw:

Posted in BitmapData, misc, pixel manipulation, setPixel | Tagged , , | 2 Comments

Overexposed Perlin Texture

Actionscript:
  1. var canvas:BitmapData = new BitmapData(1200,1200,false, 0x000000);
  2. addChild(new Bitmap(canvas));
  3.  
  4. scaleX = scaleY = 0.5;
  5. var w:int = canvas.width
  6. var hw:int = w / 2;
  7. var hhw:int = hw / 2;
  8. var size:int = canvas.width * canvas.width;
  9.  
  10. canvas.perlinNoise(hhw,hhw,2,Math.random()*100,false, false, 1, true);
  11.  
  12. for (var i:int = 0; i<size; i++){
  13.     var xp:int = i % w;
  14.     var yp:int = int(i / w);
  15.     var col:uint =  canvas.getPixel(xp, yp) / (xp+yp-w)>> 8 & 0xFF
  16.     canvas.setPixel(xp, yp, col <<16 | col <<8 | col)
  17. }
  18.  
  19. var blur:BitmapData = canvas.clone();
  20. blur.applyFilter(blur, blur.rect, new Point(0,0), new BlurFilter(10,10,1));
  21.  
  22. canvas.draw(blur, null, null, BlendMode.ADD);

I was playing around awhile back and created this snippet, it will draw something that looks like this:

this is one of those snippets that can produce vastly different looking images with minor changes to the code... for instance, try changing the blendMode to darken and line 15 to this:

var col:uint = canvas.getPixel(xp, yp) / (xp|yp-w) >> 5 & 0xFF;

and you'll end up with this:

...take the original snippet and change the blendMode to subtract:

etc...

Posted in BitmapData, misc, setPixel | Tagged , , | Leave a comment

Spring PerspectiveProjection

Actionscript:
  1. var pointNum:int = 3000;
  2. x = stage.stageWidth / 2;
  3. y = stage.stageHeight / 2;
  4.  
  5. var verts:Vector.<Number>  = new Vector.<Number>();
  6. var tVerts:Vector.<Number> = new Vector.<Number>();
  7. var pVerts:Vector.<Number> = new Vector.<Number>();
  8. var uv:Vector.<Number> = new Vector.<Number>();
  9. var cmds:Vector.<int> = new Vector.<int>();
  10.  
  11. var index:int = 0;
  12. var half:Number = pointNum / 20000;
  13. for (var i:int = 0; i<pointNum; i+=3){
  14.     verts[i] = 0.08 * Math.cos(i * Math.PI / 180);
  15.     verts[i+1] = 0.08 * Math.sin(i * Math.PI / 180);
  16.     verts[i+2] =  i / 10000 - half;
  17.     cmds[index++] = 2;
  18. }
  19. cmds[0] = 1;
  20.  
  21. var proj:PerspectiveProjection = new PerspectiveProjection();
  22. proj.fieldOfView = 45;
  23. var projMat:Matrix3D = proj.toMatrix3D();
  24. var m:Matrix3D = new Matrix3D();
  25. var dx:Number = 0, dy:Number = 0;
  26. addEventListener(Event.ENTER_FRAME, onLoop);
  27. function onLoop(evt:Event):void {
  28.        m.identity();
  29.        dx += (mouseX - dx) / 4;
  30.        dy += (mouseY - dy) / 4;
  31.        m.appendRotation(dy,Vector3D.X_AXIS);
  32.        m.appendRotation(dx,Vector3D.Y_AXIS);
  33.        m.appendTranslation(0,0,0.5);
  34.        m.transformVectors(verts, tVerts);
  35.        Utils3D.projectVectors(projMat, tVerts, pVerts, uv);
  36.        graphics.clear();
  37.        graphics.lineStyle(3,0x000000);
  38.        graphics.drawPath(cmds, pVerts);
  39. }

This snippet draws a spring shape in 3D with perspective. This is the first snippet where I've made use of the PerspectiveProjection class. So if your wondering how to add perspective to your Utils3D.projectVectors code... this is one way to do it...


Have a look at the swf...

Posted in 3D, Graphics, Video, matrix | Tagged , , | 1 Comment

Quick Pixel Sphere

Actionscript:
  1. var pointNum:int = 20000;
  2. var radius:int = 150;
  3.  
  4. var canvas:BitmapData = new BitmapData(400,400,false, 0x000000);
  5. addChild(new Bitmap(canvas));
  6. var verts:Vector.<Number>  = new Vector.<Number>();
  7. var pVerts:Vector.<Number> = new Vector.<Number>();
  8. var uv:Vector.<Number> = new Vector.<Number>();
  9.  
  10. for (var i:int = 0; i<pointNum; i+=3){
  11.     var xp:Number = Math.random() * 400 - 200;
  12.     var yp:Number = Math.random() * 400 - 200;
  13.     var zp:Number = Math.random() * 400 - 200;
  14.     var dist:Number = Math.sqrt(xp * xp + yp * yp + zp * zp);
  15.     // normalize and scale x,y,z
  16.     verts[i] = xp / dist * radius;
  17.     verts[i+1] = yp / dist * radius;
  18.     verts[i+2] = zp / dist * radius;
  19. }
  20.  
  21. var m:Matrix3D = new Matrix3D();
  22. var dx:Number = 0, dy:Number = 0;
  23. addEventListener(Event.ENTER_FRAME, onLoop);
  24. function onLoop(evt:Event):void {
  25.        m.identity();
  26.        dx += (mouseX - dx) / 4;
  27.        dy += (mouseY - dy) / 4;
  28.        m.appendRotation(dx, Vector3D.X_AXIS);
  29.        m.appendRotation(dy, Vector3D.Y_AXIS);
  30.        m.appendTranslation(200,200,0);
  31.        Utils3D.projectVectors(m, verts, pVerts, uv);
  32.        canvas.fillRect(canvas.rect, 0x000000);
  33.        for (var i:int = 0; i<pVerts.length; i+=2){
  34.          canvas.setPixel(pVerts[i], pVerts[i + 1], 0xFFFFFF);
  35.        }
  36. }

This snippet shows a quick way to randomly place a bunch of xyz coordinates on the surface of a sphere. I saw this trick in an OpenGL book a few years back - dug around my books but couldn't find it... If I find it I'll update this post.

The trick is achieved by normalizing the vector defined by each 3D coordinate...


Have a look at the swf...

Posted in 3D, BitmapData, Math, matrix, setPixel | Tagged , , | 4 Comments

Wave Trick

Actionscript:
  1. [SWF(width=800, height=600)]
  2. var dupes:int = 5
  3. var pntNum:int = 180;
  4.  
  5. var hh:Number = stage.stageHeight / 2;
  6. var points:Vector.<Number> = new Vector.<Number>();
  7. var vel:Vector.<Number> = new Vector.<Number>();
  8. var cmds:Vector.<int> = new Vector.<int>();
  9. var vectors:Vector.<Shape> = new Vector.<Shape>();
  10.  
  11. for (var i:int = 0; i<dupes; i++){
  12.     vectors[i] = Shape(addChildAt(new Shape(),0));
  13.     vectors[i].x = 10 * i;
  14.     vectors[i].y = -10 * i;
  15. }
  16. var index:int = 0;
  17. for (i = 0; i<pntNum; i++){
  18.     points[index++] = 10 + i * 4;
  19.     points[index++] = hh;
  20.     cmds[i] = 2;
  21.     vel[i] = 0;
  22. }
  23. cmds[0] = 1;
  24. addEventListener(Event.ENTER_FRAME, onLoop);
  25. function onLoop(evt:Event):void {  
  26.    index = 1;
  27.    points[index] += (mouseY - points[index]) / 12;
  28.    for (var i:int = 3; i<points.length; i+=2){
  29.          points[i] += vel[index];
  30.          vel[index] += ((points[i] - points[i - 2]) * -0.16 - vel[index]) / 4;
  31.          index++;
  32.    }
  33.    for (i = 0; i<dupes; i++){
  34.        var c:uint =  255 - 255 / i;
  35.        with (vectors[i].graphics){
  36.            clear();
  37.            lineStyle(0,c <<16 | c <<8 | c);
  38.            drawPath(cmds, points);
  39.        }
  40.    }
  41. }

This snippet uses elasticity to create an interesting wave effect. I first stumbled upon this technique back in my director days...


Have a look at the swf here...

Posted in Graphics, Vector, motion | Tagged , , | Leave a comment

Summarize Contents of Array

Actionscript:
  1. var a:Array = [true, true, true, false, false, true, true, true, false];
  2.  
  3. var counter:int = 0;
  4. var prev:Boolean;
  5. var summary:Array = [];
  6. for (var i:int = 1; i<a.length; i++){
  7.     prev = a[i - 1]
  8.     counter++;
  9.     if (prev != a[i]){
  10.         if (prev){
  11.             summary.push("true: "+ counter);
  12.         }else{
  13.             summary.push("false: "+ counter);
  14.         }
  15.         counter = 0;
  16.     }
  17. }
  18. summary.push(a[i-1].toString()+": "+ (counter+1));
  19.  
  20. trace(summary);
  21.  
  22. /** outputs:
  23. true: 3,false: 2,true: 3,false: 1
  24. */

This is a handy way to summarize the contents of an array of boolean values.

Posted in arrays, misc | Tagged , , | 8 Comments

Sphere of Squares

Actionscript:
  1. [SWF(width = 600, height = 600, backgroundColor=0x000000)]
  2. var squareNum:int  = 1000;
  3. var hw:Number = stage.stageWidth / 2;
  4. var hh:Number = stage.stageHeight / 2;
  5. // verts defines a single square
  6. var verts:Vector.<Number> = Vector.<Number>([-20, 0, 0, 20, 0, 0, 20, 0, 40, -20, 0, 40, -20, 0, 0]);
  7. var cmds:Vector.<int> = Vector.<int>([1,2,2,2,2]);
  8. var tempVerts:Vector.<Number> = new Vector.<Number>();
  9. var newVerts:Vector.<Number> = new Vector.<Number>();
  10. var pVerts:Vector.<Number> = new Vector.<Number>(10 * squareNum);
  11. var uv:Vector.<Number> = new Vector.<Number>(15 * squareNum);
  12. var vectors:Shape = new Shape();
  13. var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false, 0x000000);
  14. addChild(new Bitmap(canvas));
  15. var blurred:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false, 0x000000);
  16. var blur:BlurFilter = new BlurFilter(20,20,1);
  17.  
  18. var m:Matrix3D = new Matrix3D();
  19.  
  20. var radius:Number = 200;
  21. // duplicate the verts array a bunch of times
  22. // each time moving the square to a random place on the
  23. // circumference of a sphere
  24. for (var i:int = 0; i<squareNum; i++){
  25.     m.identity();
  26.     var s:Number = Math.random()*.5 + .5;
  27.     m.appendScale(s, s, s);
  28.     m.appendRotation(90,Vector3D.X_AXIS);
  29.     m.appendTranslation(0, 0, radius);
  30.     m.appendRotation(Math.random()*360,Vector3D.X_AXIS);
  31.     m.appendRotation(Math.random()*360,Vector3D.Y_AXIS);
  32.     m.appendRotation(Math.random()*360,Vector3D.Z_AXIS);
  33.     m.transformVectors(verts,tempVerts);
  34.     newVerts = newVerts.concat(tempVerts);
  35.     cmds = cmds.concat(Vector.<int>([1,2,2,2,2]));
  36. }
  37. newVerts.fixed = pVerts.fixed = uv.fixed = true;
  38. var dx:Number = 0, dy:Number = 0;
  39. var pnt:Point = new Point();
  40. addEventListener(Event.ENTER_FRAME, onLoop);
  41. function onLoop(evt:Event):void {
  42.        dx += (mouseX - dx) / 4;
  43.        dy += (mouseY - dy) / 4;
  44.        m.identity();
  45.        m.appendRotation(dx,Vector3D.Z_AXIS);
  46.        m.appendRotation(dy,Vector3D.X_AXIS);
  47.        m.appendTranslation(hw,hh, 0);
  48.        Utils3D.projectVectors(m, newVerts, pVerts, uv);
  49.        with(vectors.graphics){
  50.            clear();
  51.            beginFill(0xFFFFFF);
  52.            drawCircle(hw, hh, radius+10);
  53.            beginFill(0x000000);
  54.            drawPath(cmds, pVerts, GraphicsPathWinding.NON_ZERO);
  55.        }
  56.        canvas.fillRect(canvas.rect, 0x000000);
  57.        canvas.draw(vectors);
  58.        blurred.copyPixels(canvas, canvas.rect, pnt);
  59.        blurred.applyFilter(blurred,blurred.rect, pnt, blur);
  60.        canvas.draw(blurred, null, null, BlendMode.SCREEN);
  61. }

This snippet is similar to yesterdays post but the visual result is rather different. This one does a little more Matrix3D stuff resulting in a sphere made up entirely of squares. This is obscured by the size of the squares and the fact that they overlap and cut each other up. BitmapData a BlurFilter and a BlendMode give the entire thing a slight glow...


Have a look at the swf here...

Posted in 3D, BitmapData, Vector | Tagged , , , | 12 Comments

transformVectors() and drawPath()

Actionscript:
  1. var squareNum:int  = 100;
  2. // verts defines a single square
  3. var verts:Vector.<Number> = Vector.<Number>([-20, 0, 0, 20, 0, 0, 20, 0, 40, -20, 0, 40, -20, 0, 0]);
  4. var cmds:Vector.<int> = Vector.<int>([1,2,2,2,2]);
  5. var tempVerts:Vector.<Number> = new Vector.<Number>();
  6. var newVerts:Vector.<Number> = new Vector.<Number>();
  7. var pVerts:Vector.<Number> = new Vector.<Number>(10 * squareNum);
  8. var uv:Vector.<Number> = new Vector.<Number>(15 * squareNum);
  9.  
  10. var m:Matrix3D = new Matrix3D();
  11.  
  12. // duplicate the verts array a bunch of times
  13. // each time randomly rotating, scaling and translating it
  14. for (var i:int = 0; i<squareNum; i++){
  15.     m.identity();
  16.     m.appendRotation(Math.random()*360,Vector3D.X_AXIS);
  17.     m.appendRotation(Math.random()*360,Vector3D.Y_AXIS);
  18.     m.appendRotation(Math.random()*360,Vector3D.Z_AXIS);
  19.     var s:Number = Math.random()*2 + .1;
  20.     m.appendScale(s, s, s);
  21.     m.appendTranslation(Math.random()*400 - 200, Math.random()*400 - 200, Math.random()*400 - 200);
  22.     m.transformVectors(verts,tempVerts);
  23.     newVerts = newVerts.concat(tempVerts);
  24.     cmds = cmds.concat(Vector.<int>([1,2,2,2,2]));
  25. }
  26. newVerts.fixed = pVerts.fixed = uv.fixed = true;
  27.  
  28. var dx:Number = 0, dy:Number = 0;
  29. addEventListener(Event.ENTER_FRAME, onLoop);
  30. function onLoop(evt:Event):void {
  31.        dx += (mouseX - dx) / 4;
  32.        dy += (mouseY - dy) / 4;
  33.        
  34.        m.identity();
  35.        m.appendRotation(dx,Vector3D.Z_AXIS);
  36.        m.appendRotation(dy,Vector3D.X_AXIS);
  37.        m.appendTranslation(stage.stageWidth / 2,stage.stageHeight / 2, 0);
  38.  
  39.        Utils3D.projectVectors(m, newVerts, pVerts, uv);
  40.        
  41.        graphics.clear();
  42.        graphics.lineStyle(0,0x000000);
  43.        graphics.drawPath(cmds, pVerts);
  44. }

This is a demo showing how to use transformVectors() and drawPath() together. It creates 100 wireframe squares in 3D:


Have a look at the swf...

Posted in 3D, Graphics, Vector | 2 Comments