[Flash 11]
Decembre 2013
2D Lighting with ColorMatrixFilter
After reading this article on 2D lightning in game I have made a test with ColorMatrixFilter.
Full source code
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BlendMode; import flash.display.SimpleButton; import flash.display.Sprite; import flash.display.StageDisplayState; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.MouseEvent; import flash.filters.ColorMatrixFilter; import flash.filters.GlowFilter; import flash.geom.ColorTransform; import flash.geom.Point; import flash.geom.Rectangle; import flash.geom.Vector3D; /** * ... * @author YopSolo */ public class Main extends Sprite { [Embed(source="assets/diff.png")] private var DiffuseMapClass:Class; private var diffuseMap:Bitmap; [Embed(source="assets/norm.png")] private var NormalMapClass:Class; [Embed(source = "assets/Gnome-View-Fullscreen-64.png")] private var FullScreeIconClass:Class; private var normalMap:Bitmap; private var result_dat:BitmapData; private var HALF_SCREEN:Rectangle; private var HALF_WIDTH:int; private var HALF_HEIGT:int; private var halfScreenFlag:Boolean; private var light:Vector3D; private var lighting:ColorMatrixFilter private var fullscreeIncon_btn:SimpleButton; public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); HALF_WIDTH = stage.stageWidth >> 1; HALF_HEIGT = stage.stageHeight >> 1; HALF_SCREEN = new Rectangle(HALF_WIDTH, 0, HALF_WIDTH, stage.stageHeight); halfScreenFlag = true; light = new Vector3D(); lighting = new ColorMatrixFilter(); // creating the map diffuseMap = new DiffuseMapClass(); normalMap = new NormalMapClass(); // on screen result_dat = diffuseMap.bitmapData.clone(); addChild(new Bitmap(result_dat)); // fullscreen button var img:Bitmap = new FullScreeIconClass(); fullscreeIncon_btn = new SimpleButton(img, img, img, img); fullscreeIncon_btn.filters = [new GlowFilter(0xFFFF00,1, 10,10,3)]; fullscreeIncon_btn.x = stage.stageWidth - img.width - 10; fullscreeIncon_btn.y = stage.stageHeight - img.height - 10; fullscreeIncon_btn.addEventListener(MouseEvent.CLICK, _onClickFullScreen ); addChild( fullscreeIncon_btn ); // this.stage.addEventListener(MouseEvent.CLICK, _onClick); this.addEventListener(Event.ENTER_FRAME, _oef); } private function _onClickFullScreen(e:MouseEvent):void { e.stopImmediatePropagation(); stage.fullScreenSourceRect = new Rectangle(0,0,1280,760); stage.displayState = StageDisplayState.FULL_SCREEN; } private function _onClick(e:MouseEvent):void { halfScreenFlag= !halfScreenFlag; } private function _oef(e:Event):void { light.x = -1 * ((HALF_WIDTH - mouseX) / stage.stageWidth); light.y = (HALF_HEIGT - mouseY) / stage.stageHeight; light.z = 1 - (light.x * light.x) - (light.y * light.y); lighting.matrix = [2 * light.x, 2 * light.y, 2 * light.z, 0, (light.x + light.y + light.z) * -0xFF, 2 * light.x, 2 * light.y, 2 * light.z, 0, (light.x + light.y + light.z) * -0xFF, 2 * light.x, 2 * light.y, 2 * light.z, 0, (light.x + light.y + light.z) * -0xFF, 0, 0, 0, 1, 0]; result_dat.fillRect(result_dat.rect, 0x0); result_dat.applyFilter(normalMap.bitmapData, normalMap.bitmapData.rect, normalMap.bitmapData.rect.topLeft, lighting); result_dat.draw(diffuseMap.bitmapData, null, null, BlendMode.MULTIPLY, halfScreenFlag ? HALF_SCREEN : null); } } }