Category Archives: color

QuickShader Micro-Lib

In 2015 I created QuickShader… which just takes the boilerplate out of showing a shader in the browser. Here are a few examples:

Also posted in Graphics, Math, glsl, graphics algorithms, html5, javascript, motion, pixel manipulation | Tagged , | Leave a comment

Interesting Texture #3 (animated)

Actionscript:
  1. [SWF(frameRate=60, backgroundColor=0x000000, width=500, height=500)]
  2. var canvas:BitmapData = new BitmapData(500,500,false, 0x000000);
  3. addChild(new Bitmap(canvas));
  4. var clone:BitmapData = new BitmapData(500,500,false, 0x000000);
  5. var canvasRect:Rectangle = canvas.rect;
  6. var w:int = canvas.width;
  7. var w2:Number = 1/w;
  8. var w10:Number = 1/(w * 80);
  9. var convert:Number = Math.PI/180;
  10. var size:int = canvas.width * canvas.height;
  11. var pix:Vector.<uint> = new Vector.<uint>(size, true);
  12. var gray:ColorMatrixFilter = new ColorMatrixFilter([1, 0.55, 0.55, 0,0,0.55, 0.9, 0.55, 0,0,0.55, 0.55, 0.550,0, 0,0,0,1,0]);
  13. var m:Matrix = new Matrix();
  14. m.scale(1,-1);
  15. m.translate(0,canvas.height);
  16. var sin:Number = 0, cos:Number = 0;
  17. var dx:Number = 0, dy:Number = 0;
  18. var pnt:Point = new Point();
  19. var blur:BlurFilter = new BlurFilter(10,10,1);
  20. addEventListener(Event.ENTER_FRAME, onLoop);
  21. function onLoop(evt:Event):void {
  22.     canvas.lock();
  23.     dx += (mouseX * 10 - 3000 - dx) / 8;
  24.     dy += (mouseY * 4 - dy) / 8;
  25.     for (var i:int = 0; i<size; i++){
  26.         var xp:int = i % w;
  27.         var yp:int = int(i * w2);
  28.         var xp2:int = xp <<1;
  29.         var t:Number = (yp * (xp2 + dx) * w10) % 3.14687;
  30.         //compute sine
  31.         // technique from http://lab.polygonal.de/2007/07/18/fast-and-accurate-sinecosine-approximation/
  32.         // by Michael Baczynski
  33.         if (t<0) {
  34.             sin=1.27323954*t+.405284735*t*t;
  35.         } else {
  36.             sin=1.27323954*t-0.405284735*t*t;
  37.         }
  38.         // compute cosine
  39.         t = (xp2 + dy) * convert % 6.28;
  40.         t+=1.57079632;
  41.         if (t>3.14159265) {
  42.             t-=6.28318531;
  43.         }
  44.         if (t<0) {
  45.             cos=1.27323954*t+0.405284735*t*t;
  46.         } else {
  47.             cos=1.27323954*t-0.405284735*t*t;
  48.         }
  49.         var c1:int = 31 * (cos - sin);
  50.         if (c1 <0) c1 = 256 - c1;
  51.         c1 = (c1 <<2 | c1) ;
  52.         pix[i] = c1 <<15 | c1 <<9 | c1;
  53.     }
  54.     canvas.setVector(canvasRect, pix);
  55.     clone.copyPixels(canvas, canvasRect, pnt);
  56.     canvas.draw(clone, m, null, BlendMode.SUBTRACT);
  57.     clone.copyPixels(canvas, canvasRect, pnt);
  58.     clone.applyFilter(clone, canvasRect, pnt, blur);
  59.     canvas.draw(clone, null, null, BlendMode.ADD);
  60.     canvas.applyFilter(canvas, canvas.rect, new Point(0,0), gray);
  61.     canvas.unlock();
  62. }

This snippet creates an interactive animated texture. Originally this texture wasn an unoptimized messy code snippet (see the original post here) - I went through and did a few optimizations to get it running in real-time and this is the result:

Check out the swf over at wonderfl.net...

Also posted in BitmapData, Vector, pixel manipulation | Tagged , , | Leave a comment

HSV Color Type

Actionscript:
  1. [SWF(width=560,height=300,backgroundColor=0x000000,frameRate=30)]
  2.  
  3. var key:Object = new Object();
  4. var alphabet:Array = "abcdefghijklmnopqrstuvwxyz".split("");
  5.  
  6. var num:Number = alphabet.length;
  7. var step:Number = 360 / num;
  8.  
  9. var colors:Object = new Object();
  10. for (var i:int  = 0; i<num; i++){
  11.     var index:String = alphabet[i];
  12.      key[index] = 65 + i;
  13.      var c:Array = hsv(i * step, 1, 1);
  14.      colors[index] = c[0] <<16 | c[1] <<8 | c[2];
  15. }
  16. alphabet.push("32");
  17. num++;
  18. key["32"] = 32;
  19. colors["32"]  = 0x333333;
  20. x = y = 10;
  21. var count:int = 0;
  22. var size:int = 20;
  23. stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyPressed);
  24. function onKeyPressed(evt:KeyboardEvent):void{
  25.     for (var i:int= 0; i<num; i++){
  26.         var index:String = alphabet[i];
  27.          if (index == "32"){
  28.             trace("hi", evt.keyCode, key[index]);
  29.          }
  30.         if (evt.keyCode == key[index]){
  31.             graphics.beginFill(colors[index]);
  32.             var xp:int = count % num * size;
  33.             var yp:int = int(count / num) * size;
  34.             graphics.drawRect(xp, yp, size, size);
  35.             count++;
  36.         }
  37.     }
  38. }
  39. // ported from here:
  40. //http://www.cs.rit.edu/~ncs/color/t_convert.html
  41. function hsv(h:Number, s:Number, v:Number):Array{
  42.     var r:Number, g:Number, b:Number;
  43.     var i:int;
  44.     var f:Number, p:Number, q:Number, t:Number;
  45.     if (s == 0){
  46.         r = g = b = v;
  47.         return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
  48.     }
  49.     h /= 60;
  50.     i  = Math.floor(h);
  51.     f = h - i;
  52.     p = v *  (1 - s);
  53.     q = v * (1 - s * f);
  54.     t = v * (1 - s * (1 - f));
  55.     switch( i ) {
  56.         case 0:
  57.             r = v, g = t, b = p;
  58.             break;
  59.         case 1:
  60.             r = q, g = v, b = p;
  61.             break;
  62.         case 2:
  63.             r = p, g = v, b = t;
  64.             break;
  65.         case 3:
  66.             r = p, g = q, b = v;
  67.             break;
  68.         case 4:
  69.             r = t, g = p, b = v;
  70.             break;
  71.         default:        // case 5:
  72.             r = v, g = p, b = q;
  73.             break;
  74.     }
  75.     return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
  76. }

This snippet is a typing experiment - for every letter, you type a box filled with a specific color is drawn to the stage. The color associated with each letter is determined by moving through hsv color space - so typing an alphabet will end up with something resembling a spectrum.

Also posted in Graphics, UI, keys | Tagged , , | Leave a comment

Distance Render

Actionscript:
  1. var verts:Vector.<Number> = new Vector.<Number>();
  2. var pVerts:Vector.<Number> = new Vector.<Number>();
  3. var uvts:Vector.<Number> = new Vector.<Number>();
  4.  
  5. var hs:Number = 2.3;
  6. var step:Number = 0.04;
  7.  
  8. var tVerts:Vector.<Number> = new Vector.<Number>();
  9. var rVerts:Vector.<Number> = new Vector.<Number>();
  10. var matrix:Matrix3D = new Matrix3D();
  11. matrix.identity();
  12. matrix.appendRotation(45,Vector3D.Y_AXIS);
  13. matrix.appendRotation(45,Vector3D.X_AXIS);
  14. var inc:int = 0;
  15. var i:Number, j:Number, k:Number;
  16. i = hs;
  17. while( i> -hs){
  18.     j = hs;
  19.     while(j> -hs){
  20.         k = hs;
  21.         while(k> -hs){
  22.             tVerts[inc] = -i;
  23.             inc++
  24.             tVerts[inc] = -j;
  25.             inc++
  26.             tVerts[inc] = -k;
  27.             inc++
  28.             k -= step;
  29.         }
  30.         j -= step;
  31.     }
  32.     i -= step;
  33. }
  34.  
  35. matrix.transformVectors(tVerts, rVerts);
  36.  
  37. var vinc:int = 0;
  38. inc = 0
  39. var R:Number = 1.5;
  40. var r:Number = .5;
  41. for (i= -hs; i<hs; i+=step){
  42.     for (j = -hs; j<hs; j+=step){
  43.         for (k = -hs; k<hs; k+=step){
  44.             var vx:Number = rVerts[inc] ;
  45.             inc++
  46.             var vy:Number = rVerts[inc]  ;
  47.             inc++
  48.             var vz:Number=  rVerts[inc] ;
  49.             inc++
  50.             var s:Number = Math.pow(vx  * vx  + vy * vy + vz * vz + R*R - r * r, 2) - 4 * (R * R)*(vx * vx + vy * vy);
  51.             if (s <0 && s> -.5){
  52.                 verts[vinc] = (i * 50);
  53.                 vinc++
  54.                 verts[vinc] = (j * 50);
  55.                 vinc++
  56.                 verts[vinc] = (k * 50);
  57.                 vinc++
  58.                   inc += int((hs - k) / step) * 3;
  59.                   k = hs;
  60.              }
  61.         }
  62.     }
  63. }
  64.  
  65. var canvas:BitmapData = new BitmapData(400,400,false, 0x000000);
  66. addChild(new Bitmap(canvas));
  67. render();
  68. function render():void{
  69.     matrix.identity();
  70.     matrix.appendTranslation(200, 200, 0);
  71.     Utils3D.projectVectors(matrix, verts, pVerts, uvts);
  72.     canvas.lock();
  73.     canvas.fillRect(canvas.rect, 0x000000);
  74.     var inc:int = 2;
  75.     var c:int = 0;
  76.     var r:Rectangle = new Rectangle();
  77.     r.width = r.height = 2;
  78.     for (var i:int = 0; i<pVerts.length; i+=2){
  79.           r.x = pVerts[i];
  80.           r.y = pVerts[i + 1];
  81.           c = Math.max(0,100 - verts[inc]);
  82.           canvas.fillRect(r, c <<16 | c <<8 | c);
  83.           inc += 3;
  84.     }
  85.     canvas.unlock();
  86. }

This snippet uses some of the techniques from the last few posts to create a distance render - this renders the implicit equation for a torus.

Also posted in BitmapData, Math, Vector, graphics algorithms, matrix, pixel manipulation | Tagged , | Leave a comment