In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

beedama-korokoro

displacement map filterの練習用
物理演算にBox2Dを使おうとしたけど、導入に時間がかかりそうで1日1Flashを
まもれそうになかったので、擬似的に実装。振動があるけど雰囲気は楽しめると思う
玉の屈折なども完全に擬似的なもの。こちらも雰囲気だけお楽しみください
しかし、Flashはadobeなだけあってフィルタ類が充実していて高速でよいです
TODO:時間があればBox2Dで再実装
TODO:試行錯誤中にできたコードのゴミをリファクタリング
遊び方:中心からのマウスの位置でその方向に重力発生
玉をクリックすると、その玉を放り出す
玉が無いところをクリックすると、玉の追加
[Z]でランダムなサイズで玉を生成するモードに切り替え
2010.4.3 コメントアウトしていたコードを除去
2010.4.3 複数サイズの玉を出したさいの衝突判定バグ修正
2010.4.3 [Z]でランダムなサイズで玉を生成するモードに切り替え
Get Adobe Flash player
by zendenmushi 03 Apr 2010
/**
 * Copyright zendenmushi ( http://wonderfl.net/user/zendenmushi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/1qWQ
 */

// displacement map filterの練習用
// 物理演算にBox2Dを使おうとしたけど、導入に時間がかかりそうで1日1Flashを
// まもれそうになかったので、擬似的に実装。振動があるけど雰囲気は楽しめると思う
// 玉の屈折なども完全に擬似的なもの。こちらも雰囲気だけお楽しみください

// しかし、Flashはadobeなだけあってフィルタ類が充実していて高速でよいです

// TODO:時間があればBox2Dで再実装
// TODO:試行錯誤中にできたコードのゴミをリファクタリング

// 遊び方:中心からのマウスの位置でその方向に重力発生
// 玉をクリックすると、その玉を放り出す
// 玉が無いところをクリックすると、玉の追加

// [Z]でランダムなサイズで玉を生成するモードに切り替え

// 2010.4.3 コメントアウトしていたコードを除去
// 2010.4.3 複数サイズの玉を出したさいの衝突判定バグ修正
// 2010.4.3 [Z]でランダムなサイズで玉を生成するモードに切り替え
package  
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BitmapDataChannel;
	import flash.display.BlendMode;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.filters.DisplacementMapFilter;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import frocessing.core.F5BitmapData2D;
	/**
	 * ...
	 * @author TMaeda
	 */
    [SWF(width=465,height=465,backgroundColor=0xcccccc,frameRate=60)]
	public class Beedama extends Sprite
	{
		private var displacement : BitmapData;
		private var wood : BitmapData;
		private var wood2 : BitmapData;
		private var back : F5BitmapData2D;
		private var backRect : Rectangle = new Rectangle();
		private var zeroPoint : Point = new Point(0,0);
		private var temppos : Point = new Point();
		private var displaceFilter : DisplacementMapFilter;
		private var mouseIsDown : Boolean = false;
		private var mouseClicked : Boolean = false;
		private var lastPoint : Point = new Point();
		private var randomSizeMode : Boolean = false;
		
		// 
		private var tamas : Vector.<Tama> = new Vector.<Tama>;
		private var freep : int = -1;
		private const itemlimit : int = 5000;
		
		
		public function Beedama() 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event=null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			addEventListener(Event.ENTER_FRAME, enterFrame);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);

		
			wood = new BitmapData(stage.stageWidth*2, stage.stageHeight*2);
			wood2 = new BitmapData(stage.stageWidth, stage.stageHeight);
			wood.perlinNoise(stage.stageWidth * 2, stage.stageHeight / 2, 2, 0, true, false,7,true);
			
			back = new F5BitmapData2D(stage.stageWidth, stage.stageHeight, true, 0);

			displacement = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0x808080);
			displaceFilter = new DisplacementMapFilter(displacement,null,BitmapDataChannel.GREEN, BitmapDataChannel.BLUE,back.width/2, back.height/2);
			
			addChild(new Bitmap(back.bitmapData));
			backRect.x = 0;
			backRect.y = 0;
			backRect.width = stage.stageWidth;
			backRect.height = stage.stageHeight;
			
			wood2.lock();
			for (var y : int = 0; y < wood2.height; y++) {
				for (var x : int = 0; x < wood2.width; x++) {
					var sum : Number = 0;
					for (var i : int = 0; i < 4; i++) {
						var g : Number = ((wood.getPixel32(x*2 + (i & 1), y*2 + (i >> 1)) & 0xff) / 256.0) * 20;
						sum += (g - (g >> 0))*255;
					}
					
					var col : int = (sum / 4+10)*256/(256+10);
					col = 0xff000000 | ((col*0.2) << 0) | ((col*0.6) << 8) | (col << 16);
					
					wood2.setPixel32(x, y, col );
					
				}
			}
			wood2.unlock();
			randomSizeMode = false;
			clear();
			generateBalls(randomSizeMode,10);
		}
		
		private function keyDown(e:KeyboardEvent):void 
		{
			if (e.charCode == 122) {
				for (var i : int = freep; i >= 0; i--) {
					var tama : Tama = tamas[i];
					tama.drop = true;
					//remove(tama.index);
					tama.dx = tama.x > stage.stageWidth / 2 ? stage.stageWidth : 0;
					tama.dy = 0;
				}
				randomSizeMode = !randomSizeMode;
				generateBalls(randomSizeMode,10);
			}
		}
		
		public function generateBalls(randomMode : Boolean, count : int) : void
		{
			for (var ball : int = 0 ; ball < count; ball++) {
				var r : int = randomMode ? Math.random() * 40 + 24 : 32;
				var tama : Tama = newItem(Math.random() * (stage.stageWidth - r * 2) + r, Math.random() * (stage.stageHeight - r * 2) + r, 0, 0, r, back);
				if (tama) {
					tama.image.rl.r = Math.random();
					tama.image.rl.g = Math.random();
					tama.image.rl.b = Math.random();
					tama.image.tcol.r = Math.random();
					tama.image.tcol.g = Math.random();
					tama.image.tcol.b = Math.random();
					tama.image.render(r, r, true);
				}
			}
		}
		private function newItem(x : Number, y : Number , dx : Number, dy : Number, r : int, back : F5BitmapData2D ) : Tama
		{
			var cnt : int = tamas.length;
			if (((itemlimit > 0) && cnt >= itemlimit) && (freep >= cnt-1)) return null;
			
			freep++;

			if (freep == cnt) {
				tamas[cnt] = new Tama(r*2,r*2, back.bitmapData);
			} else {
				tamas[freep].regenerate(r*2,r*2, back.bitmapData);
			}
			tamas[freep].index = freep;
			tamas[freep].visible = true;
			tamas[freep].x = x;
			tamas[freep].y = y;
			tamas[freep].dx = dx;
			tamas[freep].dy = dy;
			tamas[freep].r = r;
			tamas[freep].drop = false;
			tamas[freep].dropstate = 0;
			tamas[freep].minx = false;
			tamas[freep].maxx = false;
			tamas[freep].miny = false;
			tamas[freep].maxy = false;
		
			return tamas[freep];
		}
		private function remove(index : int) : void
		{
			var cnt : int = tamas.length;
			var temp : Tama = tamas[index];
			var lastp : int = freep;

			temp.visible = false;
			if (lastp != index) {
				tamas[index] = tamas[lastp];
				tamas[index].index = index;
				tamas[lastp] = temp;
			}
			freep = lastp - 1;
			
		}
		private function clear() : void
		{
			for (var i : int = freep; i >= 0; i--) {
				var tama : Tama = tamas[i];
				remove(i);
			}
		}
		
		private function mouseUp(e:MouseEvent):void 
		{
			mouseClicked = false;
			if (Math.abs(lastPoint.x - stage.mouseX) + Math.abs(lastPoint.y - stage.mouseY) < 8) {
				mouseClicked = true;
			}
			
			mouseIsDown = false;
		}
		
		private function mouseDown(e:MouseEvent):void 
		{
			lastPoint.x = stage.mouseX;
			lastPoint.y = stage.mouseY;
			
			mouseIsDown = true;
		}
		private function enterFrame(e:Event):void 
		{
			var i : int;
			var tama : Tama, tama2 : Tama;
			var gx : Number = (stage.mouseX - stage.stageWidth / 2)/4;
			var gy : Number = (stage.mouseY - stage.stageHeight / 2)/4;
			var l : Number = Math.sqrt(gx * gx + gy * gy);
			var addflg : Boolean = mouseClicked;
			
			if (l > 0) {
				if (l >8) {
					gx = (gx/l)*10;
					gy = (gy/l)*10;
				}
			} else {
				gx = 0;
				gy = 0;
			}

			back.bitmapData.copyPixels(wood2, wood2.rect, zeroPoint);
			
			for (i = freep; i >= 0; i--) {
				tama = tamas[i];
				var ax : Number = gx;
				var ay : Number = gy;
				
				var len : Number = Math.sqrt( (tama.x - stage.mouseX) * (tama.x - stage.mouseX) + (tama.y- stage.mouseY) * (tama.y - stage.mouseY));
				if (!tama.drop) {
					if (mouseClicked) {
						if (len < tama.r) {
							tama.drop = true;
							//remove(tama.index);
							tama.dx = tama.x > stage.stageWidth / 2 ? stage.stageWidth : 0;
							tama.dy = 0;
							addflg = false;
							continue;
						} 
						
					}
				
					tama.x += tama.dx;
					tama.y += tama.dy;
					
					tama.maxx = (tama.x > stage.stageWidth - tama.r);
					if (tama.maxx) {
						tama.dx *= -1;
						tama.x = stage.stageWidth - tama.r;
					}
					
					tama.minx = (tama.x < tama.r);
					if (tama.minx) {
						tama.dx *= -1;
						tama.x = tama.r;
					}
					
					tama.maxy = (tama.y > stage.stageHeight - tama.r);
					if (tama.maxy) {
						tama.dy *= -1;
						tama.y = stage.stageHeight - tama.r;
					}

					tama.miny = (tama.y < tama.r);
					if (tama.miny) {
						tama.dy *= -1;
						tama.y = tama.r;
					}

					tama.dx += (ax - tama.dx) / 8;
					tama.dy += (ay - tama.dy) / 8;
					
				} else {
					tama.x += (tama.dx - tama.x) / 16;
					tama.y += (tama.dy - tama.y) / 4;
					tama.dropstate++;
					if (tama.dropstate > 8) remove(tama.index);
					
				}
				
			}
			
			
			back.beginDraw();
			back.stroke(0xff, 0xff, 0xff);
			back.moveTo(stage.stageWidth / 2, stage.stageHeight / 2);
			back.lineTo(stage.mouseX, stage.mouseY);
			back.endDraw();
			

			var cnt : int = tamas.length;
			for (i = freep; i >= 0; i--) {
				tama = tamas[i];
				if (!tama.drop) {
					for (var j : int = 0; j < cnt; j++) {
						if (j != i) {
							tama2 = tamas[j];
							var d : Number = dist(tama, tama2);
							var rr : int = tama.r + tama2.r;
							if ((d < rr) && (!tama2.drop)) {
								
								if (computeUnitVector(tama2.x, tama2.y, tama.x, tama.y, temppos)) {
									var ox : Number = 0;
									var oy : Number = 0;
									
									tama2.x = tama.x + rr * temppos.x;
									tama2.y = tama.y + rr * temppos.y;
									ox = tama2.dx-(d-rr) * temppos.x;
									if (tama2.minx && (tama2.x < tama2.r)) {
										ox = 0;// -tama2.x;
										tama2.x = tama2.r;
										
									} else if (tama2.maxx && (tama2.x > stage.stageWidth - tama2.r)) {
										ox = 0;// -tama2.x - (stage.stageWidth - tama2.r * 2);
										tama2.x = stage.stageWidth - tama2.r;
									}

									oy = tama2.dy-(d-rr) * temppos.y;
									if (tama2.miny && (tama2.y < tama2.r)) {
										oy = 0;// -tama2.y;
										tama2.y = tama2.r;
									} else if (tama2.maxy && (tama2.y > stage.stageHeight - tama2.r)) {
										oy = 0;// -tama2.y - (stage.stageHeight - tama2.r * 2);
										tama2.y = stage.stageHeight - tama2.r;
									}
									
									tama.dx += (d - rr) * temppos.x;
									tama.dy += (d - rr) * temppos.y;
									tama2.dx = ox;
									tama2.dy = oy;
									//tama.x += ox;
									//tama.y += oy;
								}
							}
						}
					}
				}
			}
			
			for (i = freep; i >= 0; i--) {
				tama = tamas[i];
				temppos.x = tama.x - tama.r/2;
				temppos.y = tama.y - tama.r/2;
				back.bitmapData.copyPixels(tama.image.shadowBmp, backRect, temppos, tama.image.shadowBmp, null, true);
			}
			displacement.fillRect(displacement.rect, 0xff008080);
			for (i = freep; i >= 0; i--) {
				tama = tamas[i];
				temppos.x = tama.x-tama.r ;
				temppos.y = tama.y-tama.r ;
				displacement.copyPixels(tama.image.refractionBmp, tama.image.refractionBmp.rect, temppos, null, null, true);
//				back.bitmapData.copyPixels(sphere.layerBmp, sphere.layerBmp.rect, temppos, null, null, true);
			}
			//back.bitmapData.copyPixels(displacement, displacement.rect, new Point(0, 0));
			back.bitmapData.applyFilter(back.bitmapData, back.bitmapData.rect, zeroPoint, displaceFilter);

			for (i = freep; i >= 0; i--) {
				tama = tamas[i];
				temppos.x = tama.x-tama.r;
				temppos.y = tama.y-tama.r;
				back.bitmapData.copyPixels(tama.image.layerBmp, tama.image.layerBmp.rect, temppos, null, null, true);
			}

			if (addflg) {
				var newr : int = randomSizeMode ? Math.random() * 40 + 24 : 32;
				var newtama : Tama = newItem(stage.mouseX, stage.mouseY, 0, 0, newr, back);
				newtama.image.rl.r = Math.random();
				newtama.image.rl.g = Math.random();
				newtama.image.rl.b = Math.random();
				newtama.image.tcol.r = Math.random();
				newtama.image.tcol.g = Math.random();
				newtama.image.tcol.b = Math.random();
				newtama.image.render(newr, newr, true);
			}
			
			mouseClicked = false;
		}
		
		private function dist(a : Tama, b : Tama): Number
		{
			return Math.sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
		}
		
		public function computeUnitVector(x0 : Number, y0 : Number, x1 : Number, y1 : Number, /*out*/ u : Point) : Boolean
		{
			var len : Number = Math.sqrt( (y0 - y1) * (y0 - y1) + (x0 - x1) * (x0 - x1) );
			if (len > 0) {
				u.x = (x0 - x1) / len;
				u.y = (y0 - y1) / len;
				return true;
			} else return false;
		}

		public function dotProduct(x0 : Number, y0 : Number, x1 : Number, y1 : Number) : Number
		{
			return x0 * x1 + y0 * y1;
		}
		
		public function crossProductZ(x0 : Number, y0 : Number, x1 : Number, y1 : Number) : Number
		{
			return x0 * y1 - y0 * x1;
		}

		
	}
	
}
import flash.display.Bitmap;
import flash.display.BlendMode;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.filters.BlurFilter;
import frocessing.core.F5BitmapData2D;
class Tama
{
	public var x : Number;
	public var y : Number;
	public var r : Number;
	public var dx : Number;
	public var dy : Number;
	
	public var minx : Boolean;
	public var maxx : Boolean;
	public var miny : Boolean;
	public var maxy : Boolean;

	public var index : int;
	public var visible : Boolean = false;
	public var drop : Boolean;
	public var dropstate : int;
	
	public var image : SphereRenderImage;
	
	public function Tama(width : int, height : int, back : BitmapData) 
	{
		regenerate(width, height, back);
	}
	
	public function regenerate(width : int, height : int, back : BitmapData) : void
	{
		image = new SphereRenderImage(width, height, back);
	}
}
class Point3D
{
	public var x : Number;
	public var y : Number;
	public var z : Number;
}
class Rgb 
{
	public var a : Number;
	public var r : Number;
	public var g : Number;
	public var b : Number;
	
	public function color(col : uint) : Rgb
	{
		a = (col >> 24) / 255;
		r = ((col >> 16) & 0xff) / 255;
		g = ((col >> 8) & 0xff) / 255;
		b = ((col >> 0) & 0xff) / 255;
		
		return this;
	}
	
	public static function pack32(r : Number, g : Number, b : Number, a : Number) : uint
	{
		return (Math.min(255, a * 255) << 24) | (Math.min(255, r * 255) << 16) | (Math.min(255, g * 255) << 8) | Math.min(255, b * 255);
	}
	
	public function color32() : uint
	{
		return pack32(r, g, b, a);
	}
	
}

class SphereShadow
{
	private var blur : BlurFilter = new BlurFilter(4, 4, 1);
	public var shadowBmpData : BitmapData;
	private var shadow : F5BitmapData2D;
	public var shadowAlpha : BitmapData;
	private var zeroPoint : Point = new Point(0, 0);
	private var shape : Shape;
	
	public function SphereShadow(width : int, height : int)
	{
		shadowBmpData = new BitmapData(width, height, true, 0);
	}	
	
	public function render(col : uint) : void
	{
		var sp1:Sprite = new Sprite();
			var g:Graphics = sp1.graphics;
			g.beginFill(0x000000, .6);
			g.drawCircle(shadowBmpData.width / 2, shadowBmpData.height / 2, shadowBmpData.width / 2);
			g.endFill();
			g.beginFill(col, .4);
			g.drawCircle(shadowBmpData.width*6 / 10, shadowBmpData.height*6 / 10, shadowBmpData.width / 8);
			g.endFill();
			shadowBmpData.draw(sp1);
		
		shadowBmpData.applyFilter(shadowBmpData, shadowBmpData.rect, zeroPoint, blur);
	}
}

import flash.display.BitmapData;
import flash.filters.DisplacementMapFilter;
import flash.geom.Point;

class SphereRenderImage
{
	private const PI : Number = 3.141592;
	private var width : int;
	private var height : int;
	private var radius : int;
	
	public  var layerBmp : BitmapData;
	public  var refractionBmp : BitmapData;
	public  var shadowBmp : BitmapData;
	private var backgroundBmp : BitmapData;
	private var diffuseBmp : BitmapData = null; // not use yet
	
	private var temppos : Point3D = new Point3D();
	private var dcol : Rgb = new Rgb();
	private var shadow : SphereShadow;

	
	public  var refraction : Number = 1.0;
	public  var shininess : Number = 1.0;
	public  var tcol : Rgb = new Rgb(); 
	public  var spec : Rgb = new Rgb(); 
	public  var amb : Rgb = new Rgb(); 
	public  var rl : Rgb = new Rgb(); 
	public  var bk : Rgb = new Rgb(); 
	
	
	public function SphereRenderImage(width : int, height : int, background : BitmapData) : void
	{
		this.width = width;
		this.height = height;
		this.radius = Math.min(width, height) / 2;
		
		backgroundBmp = background;
		
		layerBmp = new BitmapData(width, height, true, 0);
		refractionBmp = new BitmapData(width, height, true, 0);
		shadow = new SphereShadow(width, height);
		shadowBmp = shadow.shadowBmpData;
		
		spec.a = 1.0;
		spec.r = 1.0;
		spec.g = 1.0;
		spec.b = 1.0;

		amb.a = .0;
		amb.r = .0;
		amb.g = .0;
		amb.b = .0;
	}
	
	private function norm(x : Number, y : Number, z : Number ,/*out*/ o : Point3D) : void
	{
		var len : Number = Math.sqrt( x*x + y*y + z*z );
		o.x = x / len;
		o.y = y / len;
		o.z = z / len;
	}

	
	public function render(posx : int, posy : int, use_displace : Boolean = false) : void
	{
		shadow.render(rl.color32());
		if (use_displace) refractionBmp.lock();
		layerBmp.lock();
		var cx : int = Math.min( width, height )/2;
		var cy : int = Math.min( width, height )/2;

		var rr : Number = radius;
		var tr : int = rr >> 0;

		var tr_xscale : Number =  backgroundBmp.width / width;
		var tr_yscale : Number =  backgroundBmp.height / height;
		
		for (var i : int = 0; i < tr * 2 ; i++) {
			
			var rad1 : Number = Math.acos( ((tr-i)/tr) );
			var spanr : Number = Math.sin( rad1 ) * rr - 1;
			var y : Number = (tr-i);

			for (var j : int = 0; j < tr * 4 -1; j++) {
				var rad2 : Number = (j / rr)*PI/4;
				var x : Number = Math.cos( rad2 ) * spanr;
				var z : Number = Math.sin( rad2 ) * spanr;

				norm(0 - x, 0 - y, rr*10 - z, temppos);
				var ex : Number = temppos.x;
				var ey : Number = temppos.y;
				var ez : Number = temppos.z;

				norm(rr*10 - x,rr*10 - y,rr*10 - z, temppos);
				var lx : Number = temppos.x;
				var ly : Number = temppos.y;
				var lz : Number = temppos.z;

				norm(ex+lx,ex+lx,ex+lx, temppos);
				var hx : Number = temppos.x;
				var hy : Number = temppos.y;
				var hz : Number = temppos.z;

				norm(x,y,z, temppos);
				var nx : Number = temppos.x;
				var ny : Number = temppos.y;
				var nz : Number = temppos.z;

				var dr : Number = 0, dg : Number = 0 , db : Number = 0;
				if (diffuseBmp) {
					col = diffuseBmp.getPixel32( diffuseBmp.width * ((rad2 / PI / 1 )) , diffuseBmp.height * (rad1 / PI / 1 ));
					dcol.color(col);
					dcol.r = dcol.r * dr;
					dcol.g = dcol.g * dg;
					dcol.b = dcol.b * db;
				} else {
					dcol.r = dr;
					dcol.g = dg;
					dcol.b = db;
				}

				var tx : int = x;
				var px : int = (cx - tr) + tr - tx;
				var py : int = (cy - tr + i);
				
				if ((tcol.r != 0.0) || (tcol.g != 0.0) || (tcol.b != 0.0)) {
					var cosa : Number = nx * 0 + ny * 0 + nz * 1;
					var tr_u : Number, tr_v : Number;
					if (cosa != 0) tr_u = nx / cosa; else tr_u = 0;
					if (cosa != 0) tr_v = ny / cosa; else tr_v = 0;

					var tr_x : int = (backgroundBmp.width + ((cx+posx+tr_u*tr*refraction)*tr_xscale) >> 0) % backgroundBmp.width;
					if (tr_x < 0) tr_x = 0;

					var tr_y : int = (backgroundBmp.height + ((cy+posy+tr_v*tr*refraction)*tr_yscale) >> 0) % backgroundBmp.height;
					if (tr_y < 0) tr_y = 0;

					cosa = 1-cosa;
					var reflection : Number = (1-0.2)*cosa;//0.0 + (1-0.0)*cosa*cosa*cosa*cosa*cosa; // fresnel

					// pseudo refraction! not real! but look like
					if (use_displace) {
						var  tu : int = Math.max(Math.min(255, (tr_u*tr*refraction*tr_xscale/backgroundBmp.width)*128 + 128), 0);
						var  tv : int = Math.max(Math.min(255, (tr_v*tr*refraction*tr_yscale/backgroundBmp.height)*128 + 128), 0);
						refractionBmp.setPixel32(px, py, 0xff000000 | (tu << 8) | (tv));
						dcol.r = (1-rl.r*reflection)*(dcol.r*(1-tcol.r)) + rl.r*reflection*1;
						dcol.g = (1-rl.g*reflection)*(dcol.g*(1-tcol.g)) + rl.g*reflection*1;
						dcol.b = (1-rl.b*reflection)*(dcol.b*(1-tcol.b)) + rl.b*reflection*1;
					} else {
						if (tr_y < backgroundBmp.height) {
							col = backgroundBmp.getPixel32(tr_x, tr_y);
							bk.color(col);
							dcol.r = (1-rl.r*reflection)*(dcol.r*(1-tcol.r)+bk.r*tcol.r) + rl.r*reflection*1;
							dcol.g = (1-rl.g*reflection)*(dcol.g*(1-tcol.g)+bk.g*tcol.g) + rl.g*reflection*1;
							dcol.b = (1-rl.b*reflection)*(dcol.b*(1-tcol.b)+bk.b*tcol.b) + rl.b*reflection*1;
						} else {
							dcol.r = tcol.r;
							dcol.g = tcol.g;
							dcol.b = tcol.b;
						}
					}
				}
				
				var dot1 : Number;

				if ((tcol.r != 0.0) || (tcol.g != 0.0) || (tcol.b != 0.0)) {
					dot1 = Math.max(1, Math.abs(lx*nx + ly*ny + lz*nz));
				} else {
					dot1 = Math.max(0, lx*nx + ly*ny + lz*nz);
				}
				var kpow : Number = (shininess*128);
				var dot2 : Number = Math.pow(Math.max(0, hx*nx + hy*ny + hz*nz), kpow);

				var col : uint;
				
				if (use_displace) {
					col = Rgb.pack32(dot2*spec.r + dot1 * dcol.r + amb.r, dot2*spec.g + dot1 * dcol.g + amb.g, dot2*spec.b + dot1 * dcol.b + amb.b, dot2*spec.a+dot1*Math.max(dcol.r, dcol.g, dcol.b) );
				} else {
					col = Rgb.pack32(dot2 * spec.r + dot1 * dcol.r + amb.r,  dot2 * spec.g + dot1 * dcol.g + amb.g, dot2 * spec.b + dot1 * dcol.b + amb.b, 1 );
				}

				if ((px >= 0) && (px < width) && (py >= 0) && (py < height)) {
					layerBmp.setPixel32(px, py, col);
				}
			}
		}
		layerBmp.unlock();
		if (use_displace) refractionBmp.unlock();
	}
}