Skip to content

Instantly share code, notes, and snippets.

@jalava
Created July 31, 2011 05:53
Show Gist options
  • Save jalava/1116459 to your computer and use it in GitHub Desktop.
Save jalava/1116459 to your computer and use it in GitHub Desktop.
Nightvision filter for Away3d
package project.demo.away3d
{
import flash.display.Bitmap;
import project.demo.assets.Assets;
import flash.display3D.Context3DTextureFormat;
import away3d.core.managers.Texture3DProxy;
import away3d.containers.View3D;
import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.utils.ByteArray;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.Context3D;
import flash.display3D.Context3DProgramType;
import away3d.debug.Debug;
import com.adobe.utils.AGALMiniAssembler;
import flash.display3D.Program3D;
import away3d.core.managers.Stage3DProxy;
import flash.display3D.textures.Texture;
import away3d.cameras.Camera3D;
import flash.media.SoundMixer;
import flash.media.Sound;
import flash.display.Stage;
import away3d.filters.Filter3DBase;
import away3d.arcane;
use namespace arcane;
/**
* @author jalava
*/
public class NightVisionFilter extends Filter3DBase
{
private var _program3d:Program3D;
private var _bmp:BitmapData;
private var _texture:Texture;
private var _noiseText:Texture;
private var ONE:Vector.<Number> = Vector.<Number>([1,1,1,1]);
private var TWO:Vector.<Number> = Vector.<Number>([2,2,2,2]);
private var ZERO:Vector.<Number> = Vector.<Number>([0,0,0,0]);
private var darken:Vector.<Number> = Vector.<Number>([0.7,0.7,0.7,0.7]);
private var noise:Vector.<Number> = Vector.<Number>([0,0,0,0]);
private var math:Vector.<Number> = Vector.<Number>([0,0,0,0]);
private var cnt:uint = 0;
private var _noisebmp:BitmapData;
public function NightVisionFilter(spectrum:BitmapData, noise:BitmapData)
{
_bmp = spectrum;
_noisebmp = noise;
super(false);
}
override protected function initTextures(context : Context3D, view : View3D) : void
{
super.initTextures(context, view);
if (_texture) {
_texture.dispose();
}
_texture = context.createTexture(_bmp.width, _bmp.height, Context3DTextureFormat.BGRA, true);
_texture.uploadFromBitmapData(_bmp);
_noisebmp = new BitmapData(128, 128, false, 0);
_noisebmp.noise(34232,0,255,7,true);
_noiseText = context.createTexture(_noisebmp.width, _noisebmp.height, Context3DTextureFormat.BGRA, true);
_noiseText.uploadFromBitmapData(_noisebmp);
}
private function initProgram(context : Context3D):void
{
_program3d = context.createProgram();
_program3d.upload( new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.VERTEX, getVertexCode()),
new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.FRAGMENT, getFragmentCode())
);
}
private function invalidateProgram() : void
{
if (_program3d) {
_program3d.dispose();
_program3d = null;
}
}
override public function render(stage3DProxy : Stage3DProxy, target : Texture, camera : Camera3D, depthRender : Texture = null) : void
{
var context : Context3D = stage3DProxy._context3D;
super.render(stage3DProxy, target, camera);
if (!_program3d) initProgram(context);
if (target)
context.setRenderToTexture(target, false, 0, 0);
else
context.setRenderToBackBuffer();
cnt++;
stage3DProxy.setProgram(_program3d);
context.clear(0.0, 0.0, 0.0, 1.0);
context.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_2);
context.setVertexBufferAt(1, _vertexBuffer, 2, Context3DVertexBufferFormat.FLOAT_2);
stage3DProxy.setTextureAt(0, _inputTexture);
stage3DProxy.setTextureAt(1, _texture);
stage3DProxy.setTextureAt(2, _noiseText);
context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, ZERO, 1);
context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, ONE, 1);
context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 2, darken, 1);
noise[0]=cnt+Math.random();
noise[2]= 0.15;
noise[1]= -4.0;
noise[3]= 0.33;
context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 3, noise, 1);
context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 4, TWO, 1);
math[0]= Math.E;
math[1]= Math.E;
math[2]= Math.E;
context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 5, math, 1);
context.drawTriangles(_indexBuffer, 0, 2);
stage3DProxy.setTextureAt(0, null);
stage3DProxy.setTextureAt(1, null);
stage3DProxy.setTextureAt(2, null);
stage3DProxy.setSimpleVertexBuffer(0, null);
stage3DProxy.setSimpleVertexBuffer(1, null);
}
protected function getVertexCode() : String
{
return "mov op, va0\n"+
"mov v0, va1";
}
protected function getFragmentCode():String {
var str:String =
"mov ft2.z, fc0.z\n"+
"mov ft2.xy, v0.xy\n"+
"mul ft2.xy, ft2.xy, fc4.xy\n"+
"sub ft2.xy, ft2.xy, fc1.xy\n"+
"dp3 ft0.x, ft2.xyz, ft2.xyz \n"+
"sqt ft0.x, ft0.x \n"+
"mul ft0.x, ft0.x, fc2.x \n"+
"sub ft0.x, fc1.x, ft0.x \n"+
"sat ft0.x, ft0.x \n"+
"tex ft1, v0, fs0 <2d,linear,clamp>\n"+
"mul ft1.xyz, ft1.xyz, ft0.xxx \n"+
"mov ft3, v0 \n"+
"add ft3.xy, ft3.xy, fc3.xx \n"+
"div ft3.xy, ft3.xy, fc3.zz \n"+
"tex ft4, ft3, fs2 <2d, linear, wrap>\n"+
"mul ft4, ft4, fc3.zzzz\n"+
"mul ft4, ft4, ft0.xxxx \n"+
"add ft1.xyz, ft1.xyz, ft4.xyz\n"+
// "pow ft5.xyz, fc5.xyz, ft5.xyz\n"+ // Can Replace 2xmul + neg with this. It's slower though
"mul ft5.xyz, ft1.xyz, fc3.yyy\n"+
"mul ft5.xyz, ft5.xyz, ft5.xyz\n"+
"neg ft5,xyz, ft5.xyz\n"+
"exp ft5.xyz, ft5.xyz \n"+
"sub ft5.xyz, fc1.xyz, ft5.xyz\n"+
"dp3 ft5.xyz, ft5.xyz, fc3.www\n"+
"tex ft6, ft5.xy, fs1<2d, linear,clamp>\n"+
"mov oc, ft6\n";
return str;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment