[PB] Psychadelic Tunnel
Unfortunately flash doesn't handle too well the intense graphic calculation. WebGL version is running more fluidly.
/**
* Copyright esimov ( http://wonderfl.net/user/esimov )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/ad46
*/
package
{
import flash.geom.ColorTransform;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.Shader;
import flash.display.ShaderJob;
import flash.display.Loader;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Point;
import flash.filters.BlurFilter;
import flash.utils.getTimer;
import mx.utils.*;
import com.bit101.components.Panel;
import com.bit101.components.Style;
import com.bit101.components.Window;
import com.bit101.components.HUISlider;
import com.bit101.components.Label;
import com.bit101.components.HUISlider;
/*
* @author esimov
*/
[SWF (background = 0x00, width = "465", height = "465")]
public class PlasmaTunnel extends Sprite
{
private var _imageURL:String;
private var _shaderJob:ShaderJob;
private var _imageLoader:Loader;
private var _bmpData:BitmapData;
private var _bmp:Bitmap;
private var _dec64:Base64Decoder;
private var _shader:Shader;
private var _window:Window;
private var _deform:HUISlider;
private var _xpos:Number;
private var _ypos:Number;
private var dec64:String = "";
private var time:Number = getTimer() * 0.0001;
private const WIDTH:Number = stage.stageWidth;
private const HEIGTH:Number = stage.stageHeight;
public function PlasmaTunnel():void
{
initStage();
}
private function initStage():void
{
if (stage) init(null);
else
{
throw new Error("Stage not active");
addEventListener(Event.ADDED_TO_STAGE, init);
}
}
private function init(event:*):void
{
Wonderfl.capture_delay(10);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.quality = "medium";
stage.frameRate = 60;
//Base64 encoder string
dec64 += "pQEAAACkBgBQbGFzbWGgDG5hbWVzcGFjZQBTaW1vIEVuZHJlAKAMdmVuZG9yAHNpbW9lbmRy";
dec64 += "ZS53b3JkcHJlc3MuY29tAKAIdmVyc2lvbgABAKAMZGVzY3JpcHRpb24AUHN5Y2hhZGVsaWMg";
dec64 += "dHVubmVsIGVmZmVjdCB3aXRoIHBsYXNtYSBkZWZvcm0AoQECAAAMX091dENvb3JkAKECBAEA";
dec64 += "D2RzdAChAQIAAANyZXNvbHV0aW9uAKICbWluVmFsdWUAQ+YAAEPmAACiAmRlZmF1bHRWYWx1";
dec64 += "ZQBESAAAREgAAKICbWF4VmFsdWUARIAAAESAAAChAQECAAhkZWZvcm0AogFtaW5WYWx1ZQA8";
dec64 += "I9cKogFkZWZhdWx0VmFsdWUAPaPXCqIBbWF4VmFsdWUAPhmZmqEBAgIABmNlbnRlcgCiAm1p";
dec64 += "blZhbHVlAENmAABDZgAAogJkZWZhdWx0VmFsdWUAQ8gAAEPIAACiAm1heFZhbHVlAEQAAABE";
dec64 += "AAAAoQEBAgABdGltZQCiAW1pblZhbHVlAAAAAACiAW1heFZhbHVlAER6AAAyAwCAP8AAAB0D";
dec64 += "AGEAABAAAgMAYQIAYAAdBADBAwAAAAMEAMEDAGAABAMAwQAAsAADAwDBBAAQAB0DADEDABAA";
dec64 += "HQMAgAMAgAADAwCAAwCAADIDAEBBQAAAHQQAgAMAAAAHBACAAwBAAB0DAIADAMAAAwMAgAMA";
dec64 += "wAAyAwBAQUAAAB0EAEADAAAABwQAQAMAQAAdAwCABAAAAAEDAIAEAEAAMgMAQD3MzM0dBACA";
dec64 += "AwAAAAcEAIADAEAAHQMAgAQAAAAyAwBAP0AAAB0EAIADAEAAAwQAgAIAwAAyAwBAPczMzQQE";
dec64 += "AEADAAAAAwQAQAMAQAAdAwBABAAAAAEDAEAEAEAAHQQAgAMAQAAdAwBAAwDAAAYDAEADAIAA";
dec64 += "MgQAIEBJD/kEBAAQBACAAAMEABADAEAAHQQAQAQAwAAdAwBAAwCAAAEDAEADAMAADAQAIAIA";
dec64 += "wAAyBAAQQAAAAB0FAIAEAIAAAwUAgAQAwAANBAAgBQAAADIEABBCyAAAHQUAgAQAgAADBQCA";
dec64 += "BADAAB0EACADAEAAAQQAIAUAAAAyAwBAQsgAAAQEABADAEAAAwQAEAQAAAAMAwBABADAADIE";
dec64 += "ABBCyAAAHQUAgAMAQAADBQCABADAAB0DAEAEAIAAAQMAQAUAAAAdBAAgAwBAAAwDAEACAMAA";
dec64 += "MgQAED5MzM0dBQCAAwBAAAMFAIAEAMAADQMAQAUAAAAyBAAQQsgAAAQFAIAEAMAAAwUAgAMA";
dec64 += "QAAdAwBABAAAAAEDAEAFAAAAHQQAEAMAQAAMAwBABADAADIFAIBDSAAABAUAQAUAAAADBQBA";
dec64 += "AwBAAB0DAEADAMAAAQMAQAUAQAAdBQCAAwBAAAwDAEACAMAAMgUAQD5MzM0dBQAgAwBAAAMF";
dec64 += "ACAFAEAAHQMAQAQAAAABAwBABQCAAB0FAEAEAEAAAwUAQAMAQAAdAwBABQBAAAMDAEACAAAA";
dec64 += "DQUAQAIAwAAMBQAgBQBAADIFAEA+TMzNHQUAEAUAgAADBQAQBQBAADIFAEBDSAAABAUAIAUA";
dec64 += "QAADBQAgBQDAAB0FAEADAEAAAQUAQAUAgAAdAwBABQBAAB0FAEAEAMAAAQUAQAIAwAAMBQAg";
dec64 += "BQBAADIFAEBAAAAABAUAEAUAQAADBQAQBQCAADIFAEBAAAAABAUAIAUAQAADBQAgBQAAAB0F";
dec64 += "AEAFAMAAAQUAQAUAgAAdBQAgBQBAAAEFACAEAMAAHQUAQAUAgAABBQBABQAAAB0FACAFAEAA";
dec64 += "AQUAIAIAwAAYBQBABQCAAB0FACAFAEAAMgUAQELIAAAEBQAQBQBAAAMFABAEAIAAHQUAQAUA";
dec64 += "wAABBQBAAgDAAAwFABAFAEAAHQUAQAUAgAABBQBABQDAADIFABBCIAAABAYAgAUAwAADBgCA";
dec64 += "AwDAAB0FABAGAAAAAQUAEAIAwAAMBgCABQDAAB0FABAFAEAAAQUAEAYAAAAdBQBAAwCAAAEF";
dec64 += "AEADAMAAMgYAgELIAAAEBgBABgAAAAMGAEAFAEAADAUAQAYAQAAyBgCAQEAAAB0GAEAFAEAA";
dec64 += "AwYAQAYAAAAdBQBABQDAAAEFAEAGAEAADAUAEAUAQAAYBQBABQDAAB0FABAFAEAAHQUAQAQA";
dec64 += "wAABBQBABQAAAA0GAIAFAEAAHQUAQAUAwAABBQBABgAAAB0GAIAFAAAAAQYAgAMAQAANBgBA";
dec64 += "BgAAAB0GAIAFAEAAAQYAgAYAQAAMBQBABgAAABgGAIAFAEAAMgUAQELIAAAEBgBABQBAAAMG";
dec64 += "AEADAMAAHQUAQAYAQAABBQBAAgDAAAwGAEAFAEAAHQUAQAYAAAABBQBABgBAAB0GAIAFAEAA";
dec64 += "HQcAgAUAgAAdBwBABQDAAB0HACAGAAAAMgUAQD+AAAAdBwAQBQBAAB0BAPMHABsA";
_bmpData = new BitmapData(WIDTH, HEIGTH, false, 0x00);
_bmp = new Bitmap(_bmpData);
_bmp.smoothing = false;
addChild(_bmp);
controlPanel();
_dec64 = new Base64Decoder;
_dec64.decode(dec64);
_shader = new Shader(_dec64.drain());
_xpos = _bmp.mouseX;
_ypos = _bmp.mouseY;
_shader.data.resolution.value = [WIDTH*1.5, HEIGTH*1.5];
_shader.data.deform.value = [_deform.value];
onStageResize(null);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
stage.addEventListener(Event.RESIZE, onStageResize);
addEventListener(Event.ENTER_FRAME, loop);
}
private function controlPanel():void
{
_window = new Window(this, WIDTH - 100, 0, "Effect adjuster");
_window.draggable = true;
_window.hasMinimizeButton = false;
_window.width = 120;
_window.height = 45;
addChild(_window);
_deform = new HUISlider(_window, 8, 24,null);
_deform.width = _window.width;
_deform.setSliderParams(0.0, 10.0, 0.0);
}
private function loop(event:Event):void
{
_shaderJob = new ShaderJob(_shader, _bmpData);
_shaderJob.start();
_xpos += (_bmp.mouseX - _xpos) * 0.1;
_ypos += (_bmp.mouseY - _ypos) * 0.1;
time += 0.02;
_shader.data.time.value = [time];
_shader.data.deform.value = [_deform.value];
}
private function onMouseMove(event:MouseEvent):void
{
_shader.data.center.value = [_xpos, _ypos];
}
private function onStageResize(event:Event):void
{
_bmp.x = (stage.stageWidth - _bmp.width) >> 1;
_bmp.y = (stage.stageHeight - _bmp.height) >> 1;
}
}
}
/***********************
* Pixelbender Shader
***********************/
/*<languageVersion : 1.0;>
kernel Plasma
< namespace : "Simo Endre";
vendor : "simoendre.wordpress.com";
version : 1;
description : "Psychadelic tunnel effect with plasma deform";
>
{
input image4 src;
output pixel4 dst;
parameter float2 resolution
<
minValue : float2 (460.0, 460.0);
defaultValue : float2 (800.0, 800.0);
maxValue : float2 (1024.0, 1024.0);
>;
parameter float deform
<
minValue : float (0.01);
defaultValue : float (0.08);
maxValue : float (0.15);
>;
parameter float2 center
<
minValue : float2 (230.0, 230.0);
defaultValue : float2 (400.0, 400.0);
maxValue : float2 (512.0, 512.0);
>;
parameter float time
<
minValue : float (0.0);
maxValue : float (1000.0);
>;
void evaluatePixel()
{
//get the coordinate for every pixel
float2 p = 1.5*(outCoord()-center)/resolution;
//apply the tunnel effect
float2 uv;
float r = pow( pow(p.x*p.x,12.0) + pow(p.y*p.y,12.0), 1.0/10.0 );
uv.x = .75*time+.1/r;
uv.y = atan(p.y,p.x)/3.1416;
//calculate some random plasma effect movement
//deform the plasma by applying the tunnel effect
float mov0 = p.x+p.y+cos(sin(time)*2.)*100.+sin(uv.x/100.)*100.;
float mov1 = uv.x + cos(sin(time)*0.2)/100.0;
float mov2 = p.y + sin(mov1)/200.;
float mov3 = uv.y*(uv.x+(sin(time)*0.2))*deform + sin(cos(time))*0.2/200.;
//combine the plasma and tunnel effect and calculate the colors for the three base channel
float c1 = abs(sin(mov1+time)/2.+mov2/2.+mov1+mov2+time);
float c2 = abs(sin(c1+sin(mov0/100.+time)+sin(p.y/40.+time)+sin((p.x+p.y)/100.)*3.));
float c3 = abs(sin(c2+cos(mov1+mov2)+cos(mov2+mov3)))+sin(p.y/100.+time);
dst = pixel4(c1,c2,c3,1.0);
}
}*/
/***********************
* Fragment Shader
* You can copy and paste to iq ShaderToy to see the difference http://www.iquilezles.org/apps/shadertoy/
***********************/
/*#ifdef GL_ES
precision highp float;
#endif
uniform vec2 resolution;
uniform float time;
void main(void)
{
vec2 uv;
vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
float r = pow( pow(p.x*p.x,16.0) + pow(p.y*p.y,16.0), 1.0/16.0 );
//float r = sqrt(dot(p,p));
//uv.x = .5*time + 2.5/r;
//uv.y = 1.0*atan(p.y,p.x)/3.1416;
uv.x = .75*time+.1/r;
uv.y = atan(p.y,p.x)/3.1416;
float mov0 = p.x+p.y+cos(sin(time)*2.)*100.+sin(uv.x/100.)*100.;
float mov1 = uv.x + cos(sin(time)*0.2)/100.0;
float mov2 = p.y + sin(mov1)/200.;
float mov3 = uv.y*(uv.x+(sin(time)*0.2))*0.09 + sin(cos(time))*0.2/200.;
float c1 = abs(sin(mov1+time)/2.+mov2/2.+mov1+mov2+time);
float c2 = abs(sin(c1+sin(mov0/100.+time)+sin(p.y/40.+time)+sin((p.x+p.y)/100.)*3.));
float c3 = abs(sin(c2+cos(mov1+mov2)+cos(mov2+mov3)))+sin(p.y/100.+time);
vec3 col = vec3(c1,c2,c3);
gl_FragColor = vec4(col,1.0);
}*/