Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
package com.lunaticpandora.effects
{
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.filters.BlurFilter;
import flash.filters.ColorMatrixFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import net.flashpunk.Entity;
import net.flashpunk.FP;
/**
* ==============================
* EFFECTS/MOTIONBLUREFFECT CLASS
* ==============================
*
* This applies some crazy effects to the whole screen using a
* post-process shader
*/
public class MotionBlurEffect extends Entity
{
private static const POINT_ZERO: Point = new Point;
private static var m_MotionBlurBitmap: BitmapData = new BitmapData(FP.width, FP.height, false, 0x000000);
public static var motion_blur_amount: Number = 0.875; //amount of blurring to apply. This controls the opacity of the motion blur
public static var motion_blur_offset: Number = 50; //pixel offset of 'double vision effect'
public static var motion_blur_enabled: Boolean = true;
private var m_ScaleVal: Number = 1.000;
private var m_ReverseScale: Boolean = false;
private var m_ScaleVariance: Number = 0.000;
private var m_ScaleTime: Number = 0;
private var m_ColourTransform: ColorTransform = new ColorTransform(1, 1, 1, motion_blur_amount);
private var m_ColourTintFilter: ColorMatrixFilter;
private var m_BlurFilter: BlurFilter = new BlurFilter(10, 10, 1);
private var m_Matrix: Matrix = new Matrix;
private var m_PixelShader: String;
private var m_PixelConstants: Vector.<Number> = new Vector.<Number>;
/**
* Constructor
*/
public function MotionBlurEffect()
{
layer = -98; //affect everything except for HUD elements (-100 +)
var matrix:Array = new Array();
matrix = matrix.concat([0.6, 0.1, 0.1, 0, 0]); // red
matrix = matrix.concat([0.1, 0.6, 0.1, 0, 0]); // green
matrix = matrix.concat([0.1, 0.1, 0.6, 0, 0]); // blue
matrix = matrix.concat([0, 0, 0, 1, 0]); // alpha
m_ColourTintFilter = new ColorMatrixFilter(matrix);
//pixel shader
m_PixelShader = new String(
"tex ft0, v1, fs0 <2d,clamp,linear,mipnone> \n" + // sample the texture
"add ft2, v1.xyzw, fc1.xyzw \n" + //calc offset
"tex ft1, ft2, fs0 <2d,clamp,linear,mipnone> \n" + // sample the texture again at the offset
"add ft0, ft0.xyzw, ft1.xyzw \n" + //average samples
"mul ft0, ft0.xyzw, fc1.wwww \n" +
"mul oc, ft0.xyzw, fc0.xyzw \n" //output colour
);
m_PixelConstants.length = 0;
m_PixelConstants.push(1.5, 1.5, 1.5, 1);
m_PixelConstants.push(0.05, 0, 0, 0.5);
}
/**
* Render function. Handles rendering of the effect
*/
public override function render(): void
{
if(motion_blur_enabled == false)
{
if(FP.stage3D)
{
FP.screen.clearPostProcessShader(); //no post process shader
}
return;
}
if(FP.stage3D)
{
m_PixelConstants[0] = 1.0 + (motion_blur_amount * 1.33);
m_PixelConstants[1] = 1.0 + (motion_blur_amount * 1.33);
m_PixelConstants[2] = 1.0 + (motion_blur_amount * 1.33);
m_PixelConstants[4] = motion_blur_offset / 1000;
FP.screen.setPostProcessShader(m_PixelShader);
FP.screen.setPostProcessShaderConstants(m_PixelConstants);
return;
}
m_Matrix.identity();
m_Matrix.translate(motion_blur_offset * motion_blur_amount, 0);
m_BlurFilter.blurX = 10 * motion_blur_amount;
m_BlurFilter.blurY = 10 * motion_blur_amount;
m_ColourTransform.alphaMultiplier = motion_blur_amount;
m_MotionBlurBitmap.applyFilter(FP.buffer, FP.buffer.rect, FP.zero, m_BlurFilter);
m_MotionBlurBitmap.applyFilter(FP.buffer, FP.buffer.rect, FP.zero, m_ColourTintFilter);
FP.buffer.draw(m_MotionBlurBitmap, m_Matrix, m_ColourTransform, BlendMode.ADD);
m_MotionBlurBitmap.copyPixels(FP.buffer, FP.buffer.rect, POINT_ZERO); //m_MotionBlurBitmap now contains a copy of the last frame's screen
}
public static function clear(): void
{
m_MotionBlurBitmap.fillRect(m_MotionBlurBitmap.rect, 0);
}
/**
* Removed function - called when the entity is removed from the world
*/
public override function removed(): void
{
m_MotionBlurBitmap.dispose(); //dispose of the motion blur bitmap
}
/**
* Auxiliary function to scale around a defined centrepoint
* @param matrix matrix to use as base for scale
* @param width width of the object to scale (for the whole screen, use FP.width)
* @param height height of the object to scale (for the whole screen, use FP.height)
* @param scale_x amount to scale on the x axis, 1 is no scaling
* @param scale_y amount to scale on the y axis, 1 is no scaling
* @return new matrix that has been scaled appropriately
*/
private function scalec(matrix: Matrix, width: Number, height: Number, scale_x: Number, scale_y: Number): Matrix
{
matrix.translate(-(width / 2), -(height / 2));
matrix.scale(scale_x, scale_y);
matrix.translate(width / 2, height / 2);
return matrix;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment