diff --git a/examples/wip/classicTunnelFilter.js b/examples/wip/classicTunnelFilter.js
new file mode 100644
index 00000000..89bce09c
--- /dev/null
+++ b/examples/wip/classicTunnelFilter.js
@@ -0,0 +1,96 @@
+PIXI.TunnelFilter = function(width, height, texture)
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ var d = new Date();
+
+ var dates = [
+ d.getFullYear(), // the year (four digits)
+ d.getMonth(), // the month (from 0-11)
+ d.getDate(), // the day of the month (from 1-31)
+ d.getHours()*60.0*60 + d.getMinutes()*60 + d.getSeconds()
+ ];
+
+ this.uniforms = {
+ iResolution: { type: 'f3', value: { x: width, y: height, z: 0 }},
+ iGlobalTime: { type: 'f', value: 1 },
+ iDate: { type: 'f4', value: dates },
+ iChannel0: { type: 'sampler2D', value: texture, wrap: 'repeat' }
+ };
+
+ // Shader by 4rknova (https://www.shadertoy.com/view/lssGDn)
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "uniform vec3 iResolution;",
+ "uniform float iGlobalTime;",
+ "uniform float iChannelTime[4];",
+ "uniform vec4 iMouse;",
+ "uniform vec4 iDate;",
+ "uniform vec3 iChannelResolution[4];",
+ "uniform sampler2D iChannel0;",
+ "// add any extra uniforms here",
+
+ "#ifdef GL_ES",
+ "precision highp float;",
+ "#endif",
+
+ "#define S 0.79577471545 // Precalculated 2.5 / PI",
+ "#define E 0.0001",
+
+ "void main(void)",
+ "{",
+ "vec2 p = (2.0 * gl_FragCoord.xy / iResolution.xy - 1.0)",
+ "* vec2(iResolution.x / iResolution.y, 1.0);",
+ "vec2 t = vec2(S * atan(p.x, p.y), 1.0 / max(length(p), E));",
+ "vec3 c = texture2D(iChannel0, t + vec2(iGlobalTime * 0.1, iGlobalTime)).xyz;",
+ "gl_FragColor = vec4(c / (t.y + 0.5), 1.0);",
+ "}"
+ ];
+
+}
+
+PIXI.TunnelFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.TunnelFilter.prototype.constructor = PIXI.TunnelFilter;
+
+Object.defineProperty(PIXI.TunnelFilter.prototype, 'iGlobalTime', {
+ get: function() {
+ return this.uniforms.iGlobalTime.value;
+ },
+ set: function(value) {
+ this.uniforms.iGlobalTime.value = value;
+ }
+});
+
+var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('texture', 'wip/tex00.jpg');
+
+}
+
+var filter;
+var sprite;
+
+function create() {
+
+ sprite = game.add.sprite(0, 0, 'texture');
+ sprite.width = 800;
+ sprite.height = 600;
+
+ filter = new PIXI.TunnelFilter(sprite.width, sprite.height, sprite.texture);
+
+ sprite.filters = [filter];
+
+}
+
+function update() {
+
+ filter.iGlobalTime = game.time.totalElapsedSeconds();
+
+}
+
+function render() {
+}
diff --git a/examples/wip/deformStarFilter.js b/examples/wip/deformStarFilter.js
index b62695e5..6ec09516 100644
--- a/examples/wip/deformStarFilter.js
+++ b/examples/wip/deformStarFilter.js
@@ -17,7 +17,7 @@ PIXI.DeformStarFilter = function(width, height, texture)
iResolution: { type: 'f3', value: { x: width, y: height, z: 0 }},
iGlobalTime: { type: 'f', value: 1 },
iDate: { type: 'f4', value: dates },
- iChannel0: { type: 'sampler2D', value: texture }
+ iChannel0: { type: 'sampler2D', value: texture, wrap: 'repeat' }
};
// Shader by iq (https://www.shadertoy.com/view/4dXGRn)
diff --git a/examples/wip/filter.js b/examples/wip/filter.js
index 994aa2da..10ac4704 100644
--- a/examples/wip/filter.js
+++ b/examples/wip/filter.js
@@ -17,7 +17,7 @@ PIXI.StarNestFilter = function(width, height, texture)
iResolution: { type: 'f3', value: { x: width, y: height, z: 0 }},
iGlobalTime: { type: 'f', value: 1 },
iDate: { type: 'f4', value: dates },
- iChannel0: { type: 'sampler2D', value: texture }
+ iChannel0: { type: 'sampler2D', value: texture, wrap: 'repeat' }
};
// Shader by Kali (https://www.shadertoy.com/view/4dfGDM)
@@ -32,43 +32,38 @@ PIXI.StarNestFilter = function(width, height, texture)
"uniform sampler2D iChannel0;",
"// add any extra uniforms here",
- "#define M_PI 3.1415926535897932384626433832795",
+ "#ifdef GL_ES",
+ "precision highp float;",
+ "#endif",
- "float rand(vec2 co)",
- "{",
- "return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);",
- "}",
+ "#define PI 3.1416",
"void main(void)",
"{",
- "float size = 30.0;",
- "float prob = 0.95;",
+ "//map the xy pixel co-ordinates to be between -1.0 to +1.0 on x and y axes",
+ "//and alter the x value according to the aspect ratio so it isn't 'stretched'",
+ "vec2 p = (2.0 * gl_FragCoord.xy / iResolution.xy - 1.0)",
+ "* vec2(iResolution.x / iResolution.y, 1.0);",
- "vec2 pos = floor(1.0 / size * gl_FragCoord.xy);",
+ "//now, this is the usual part that uses the formula for texture mapping a ray-",
+ "//traced cylinder using the vector p that describes the position of the pixel",
+ "//from the centre.",
+ "vec2 uv = vec2(atan(p.y, p.x) * 1.0/PI, 1.0 / sqrt(dot(p, p))) * vec2(2.0, 1.0);",
- "float color = 0.0;",
- "float starValue = rand(pos);",
- "if (starValue > prob)",
- "{",
- "vec2 center = size * pos + vec2(size, size) * 0.5;",
+ "//now this just 'warps' the texture read by altering the u coordinate depending on",
+ "//the val of the v coordinate and the current time",
+ "uv.x += sin(2.0 * uv.y + iGlobalTime * 0.5);",
- "float t = 0.9 + 0.2 * sin(iGlobalTime + (starValue - prob) / (1.0 - prob) * 45.0);",
+ "vec3 c = texture2D(iChannel0, uv).xyz",
- "color = 1.0 - distance(gl_FragCoord.xy, center) / (0.5 * size);",
- "color = color * t / (abs(gl_FragCoord.y - center.y)) * t / (abs(gl_FragCoord.x - center.x));",
- "}",
- "else if (rand(gl_FragCoord.xy / iResolution.xy) > 0.996)",
- "{",
- "float r = rand(gl_FragCoord.xy);",
- "color = r * (0.25 * sin(iGlobalTime * (r * 5.0) + 720.0 * r) + 0.75);",
- "}",
+ "//this divison makes the color value 'darker' into the distance, otherwise",
+ "//everything will be a uniform brightness and no sense of depth will be present.",
+ "/ (uv.y * 0.5 + 1.0);",
- "gl_FragColor = vec4(vec3(color), 1.0);",
+ "gl_FragColor = vec4(c, 1.0);",
"}"];
-
-
}
PIXI.StarNestFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
@@ -87,8 +82,7 @@ var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: p
function preload() {
- // game.load.image('texture', 'wip/64x64.png');
- game.load.image('texture', 'wip/tex08.jpg');
+ game.load.image('texture', 'wip/tex00.jpg');
}
diff --git a/examples/wip/hueRotationFilter.js b/examples/wip/hueRotationFilter.js
new file mode 100644
index 00000000..06cf3f48
--- /dev/null
+++ b/examples/wip/hueRotationFilter.js
@@ -0,0 +1,118 @@
+PIXI.HueRotationFilter = function(width, height, texture)
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ var d = new Date();
+
+ var dates = [
+ d.getFullYear(), // the year (four digits)
+ d.getMonth(), // the month (from 0-11)
+ d.getDate(), // the day of the month (from 1-31)
+ d.getHours()*60.0*60 + d.getMinutes()*60 + d.getSeconds()
+ ];
+
+ this.uniforms = {
+ iResolution: { type: 'f3', value: { x: width, y: height, z: 0 }},
+ iGlobalTime: { type: 'f', value: 1 },
+ iDate: { type: 'f4', value: dates },
+ iChannel0: { type: 'sampler2D', value: texture }
+ };
+
+ // Shader by Daniil (https://www.shadertoy.com/view/4sl3DH)
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "uniform vec3 iResolution;",
+ "uniform float iGlobalTime;",
+ "uniform float iChannelTime[4];",
+ "uniform vec4 iMouse;",
+ "uniform vec4 iDate;",
+ "uniform vec3 iChannelResolution[4];",
+ "uniform sampler2D iChannel0;",
+ "// add any extra uniforms here",
+
+ "/* Simple hue rotation filter based on article:",
+ "http://beesbuzz.biz/code/hsv_color_transforms.php",
+ "*/",
+
+ "#define SPEED 10.0",
+
+ "void main(void)",
+ "{",
+ "vec2 uv = gl_FragCoord.xy / iResolution.xy;",
+
+ "float c = cos(iGlobalTime*SPEED);",
+ "float s = sin(iGlobalTime*SPEED);",
+
+ "mat4 hueRotation =",
+ "mat4( 0.299, 0.587, 0.114, 0.0,",
+ "0.299, 0.587, 0.114, 0.0,",
+ "0.299, 0.587, 0.114, 0.0,",
+ "0.000, 0.000, 0.000, 1.0) +",
+
+ "mat4( 0.701, -0.587, -0.114, 0.0,",
+ "-0.299, 0.413, -0.114, 0.0,",
+ "-0.300, -0.588, 0.886, 0.0,",
+ "0.000, 0.000, 0.000, 0.0) * c +",
+
+ "mat4( 0.168, 0.330, -0.497, 0.0,",
+ "-0.328, 0.035, 0.292, 0.0,",
+ "1.250, -1.050, -0.203, 0.0,",
+ "0.000, 0.000, 0.000, 0.0) * s;",
+
+ "vec4 pixel = texture2D(iChannel0, uv);",
+
+ "gl_FragColor = pixel * hueRotation;",
+
+ "}"];
+
+
+
+}
+
+PIXI.HueRotationFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.HueRotationFilter.prototype.constructor = PIXI.HueRotationFilter;
+
+Object.defineProperty(PIXI.HueRotationFilter.prototype, 'iGlobalTime', {
+ get: function() {
+ return this.uniforms.iGlobalTime.value;
+ },
+ set: function(value) {
+ this.uniforms.iGlobalTime.value = value;
+ }
+});
+
+var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ // game.load.image('texture', 'wip/64x64.png');
+ // game.load.image('texture', 'wip/64x64.png');
+ game.load.image('texture', 'assets/pics/ra_einstein.png');
+
+}
+
+var filter;
+var sprite;
+
+function create() {
+
+ sprite = game.add.sprite(0, 0, 'texture');
+ // sprite.width = 800;
+ // sprite.height = 600;
+
+ filter = new PIXI.HueRotationFilter(sprite.width, sprite.height, sprite.texture);
+
+ sprite.filters = [filter];
+
+}
+
+function update() {
+
+ filter.iGlobalTime = game.time.totalElapsedSeconds();
+
+}
+
+function render() {
+}
diff --git a/examples/wip/mengerTunnelFilter.js b/examples/wip/mengerTunnelFilter.js
new file mode 100644
index 00000000..cf724865
--- /dev/null
+++ b/examples/wip/mengerTunnelFilter.js
@@ -0,0 +1,163 @@
+PIXI.MengerTunnelFilter = function(width, height, texture)
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ var d = new Date();
+
+ var dates = [
+ d.getFullYear(), // the year (four digits)
+ d.getMonth(), // the month (from 0-11)
+ d.getDate(), // the day of the month (from 1-31)
+ d.getHours()*60.0*60 + d.getMinutes()*60 + d.getSeconds()
+ ];
+
+ this.uniforms = {
+ iResolution: { type: 'f3', value: { x: width, y: height, z: 0 }},
+ iGlobalTime: { type: 'f', value: 1 },
+ iDate: { type: 'f4', value: dates },
+ iChannel0: { type: 'sampler2D', value: texture, wrap: 'repeat' }
+ };
+
+ // Shader by fb39ca4 (https://www.shadertoy.com/view/XslGzl)
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "uniform vec3 iResolution;",
+ "uniform float iGlobalTime;",
+ "uniform float iChannelTime[4];",
+ "uniform vec4 iMouse;",
+ "uniform vec4 iDate;",
+ "uniform vec3 iChannelResolution[4];",
+ "uniform sampler2D iChannel0;",
+ "// add any extra uniforms here",
+
+ "const int MAX_RAY_STEPS = 64;",
+ "const float RAY_STOP_TRESHOLD = 0.0001;",
+ "const int MENGER_ITERATIONS = 5;",
+
+ "float maxcomp(vec2 v) { return max(v.x, v.y); }",
+
+ "float sdCross(vec3 p) {",
+ "p = abs(p);",
+ "vec3 d = vec3(max(p.x, p.y),",
+ "max(p.y, p.z),",
+ "max(p.z, p.x));",
+ "return min(d.x, min(d.y, d.z)) - (1.0 / 3.0);",
+ "}",
+
+ "float sdCrossRep(vec3 p) {",
+ "vec3 q = mod(p + 1.0, 2.0) - 1.0;",
+ "return sdCross(q);",
+ "}",
+
+ "float sdCrossRepScale(vec3 p, float s) {",
+ "return sdCrossRep(p * s) / s;",
+ "}",
+
+ "float scene(vec3 p) {",
+ "float scale = 1.0;",
+ "float dist = 0.0;",
+ "for (int i = 0; i < MENGER_ITERATIONS; i++) {",
+ "dist = max(dist, -sdCrossRepScale(p, scale));",
+ "scale *= 3.0;",
+ "}",
+ "return dist;",
+ "}",
+
+ "vec3 hsv2rgb(vec3 c)",
+ "{",
+ "vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);",
+ "vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);",
+ "return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);",
+ "}",
+
+ "vec4 colorize(float c) {",
+
+ "float hue = mix(0.6, 1.15, min(c * 1.2 - 0.05, 1.0));",
+ "float sat = 1.0 - pow(c, 4.0);",
+ "float lum = c;",
+ "vec3 hsv = vec3(hue, sat, lum);",
+ "vec3 rgb = hsv2rgb(hsv);",
+ "return vec4(rgb, 1.0);",
+ "}",
+
+
+ "void main(void)",
+ "{",
+ "vec2 screenPos = gl_FragCoord.xy / iResolution.xy * 2.0 - 1.0;",
+ "vec2 mousePos = iMouse.xy / iResolution.xy * 2.0 - 1.0;",
+
+ "vec3 cameraPos = vec3(0.16 * sin(iGlobalTime), 0.16 * cos(iGlobalTime), iGlobalTime);",
+ "//vec3 cameraPos = vec3(0.0);",
+ "vec3 cameraDir = vec3(0.0, 0.0, 1.0);",
+ "vec3 cameraPlaneU = vec3(1.0, 0.0, 0.0);",
+ "vec3 cameraPlaneV = vec3(0.0, 1.0, 0.0) * (iResolution.y / iResolution.x);",
+
+ "vec3 rayPos = cameraPos;",
+ "vec3 rayDir = cameraDir + screenPos.x * cameraPlaneU + screenPos.y * cameraPlaneV;",
+
+ "rayDir = normalize(rayDir);",
+
+ "float dist = scene(rayPos);",
+ "int stepsTaken;",
+ "for (int i = 0; i < MAX_RAY_STEPS; i++) {",
+ "if (dist < RAY_STOP_TRESHOLD) {",
+ "continue;",
+ "}",
+ "rayPos += rayDir * dist;",
+ "dist = scene(rayPos);",
+ "stepsTaken = i;",
+ "}",
+
+ "vec4 color = colorize(pow(float(stepsTaken) / float(MAX_RAY_STEPS), 0.9));",
+
+ "gl_FragColor = color;",
+ "}"];
+
+
+}
+
+PIXI.MengerTunnelFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.MengerTunnelFilter.prototype.constructor = PIXI.MengerTunnelFilter;
+
+Object.defineProperty(PIXI.MengerTunnelFilter.prototype, 'iGlobalTime', {
+ get: function() {
+ return this.uniforms.iGlobalTime.value;
+ },
+ set: function(value) {
+ this.uniforms.iGlobalTime.value = value;
+ }
+});
+
+var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('texture', 'wip/tex15.png');
+
+}
+
+var filter;
+var sprite;
+
+function create() {
+
+ sprite = game.add.sprite(0, 0, 'texture');
+ sprite.width = 800;
+ sprite.height = 600;
+
+ filter = new PIXI.MengerTunnelFilter(sprite.width, sprite.height, sprite.texture);
+
+ sprite.filters = [filter];
+
+}
+
+function update() {
+
+ filter.iGlobalTime = game.time.totalElapsedSeconds();
+
+}
+
+function render() {
+}
diff --git a/examples/wip/shadertoy-effect.js b/examples/wip/shadertoy-effect.js
new file mode 100644
index 00000000..552b50ed
--- /dev/null
+++ b/examples/wip/shadertoy-effect.js
@@ -0,0 +1,1200 @@
+var vsSource = [
+ "attribute vec2 pos;",
+ "void main()",
+ "{",
+ "gl_Position = vec4(pos.x,pos.y,0.0,1.0);",
+ "}"
+ ].join("\n");
+
+
+var fsSource = [
+ "void main()",
+ "{",
+ "gl_FragColor = vec4(0.0,0.0,0.0,1.0);",
+ "}"
+ ].join("\n");
+
+//--------------------------------------
+
+function createGLTexture( ctx, image, format, texture )
+{
+ if( ctx==null ) return;
+
+ ctx.bindTexture( ctx.TEXTURE_2D, texture);
+ ctx.pixelStorei( ctx.UNPACK_FLIP_Y_WEBGL, false );
+ ctx.texImage2D( ctx.TEXTURE_2D, 0, format, ctx.RGBA, ctx.UNSIGNED_BYTE, image);
+ ctx.texParameteri( ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR);
+ ctx.texParameteri( ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR_MIPMAP_LINEAR);
+ ctx.texParameteri( ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.REPEAT);
+ ctx.texParameteri( ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.REPEAT);
+ ctx.generateMipmap(ctx.TEXTURE_2D);
+ ctx.bindTexture(ctx.TEXTURE_2D, null);
+}
+
+function createGLTextureLinear( ctx, image, texture )
+{
+ if( ctx==null ) return;
+
+ ctx.bindTexture( ctx.TEXTURE_2D, texture);
+ ctx.pixelStorei( ctx.UNPACK_FLIP_Y_WEBGL, false );
+ ctx.texImage2D( ctx.TEXTURE_2D, 0, ctx.RGBA, ctx.RGBA, ctx.UNSIGNED_BYTE, image);
+ ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR);
+ ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR);
+ ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE);
+ ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE);
+ ctx.bindTexture(ctx.TEXTURE_2D, null);
+}
+
+
+function createGLTextureNearestRepeat( ctx, image, texture )
+{
+ if( ctx==null ) return;
+
+ ctx.bindTexture(ctx.TEXTURE_2D, texture);
+ ctx.pixelStorei( ctx.UNPACK_FLIP_Y_WEBGL, false );
+ ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA, ctx.RGBA, ctx.UNSIGNED_BYTE, image);
+ ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.NEAREST);
+ ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.NEAREST);
+ ctx.bindTexture(ctx.TEXTURE_2D, null);
+}
+
+function createGLTextureNearest( ctx, image, texture )
+{
+ if( ctx==null ) return;
+
+ ctx.bindTexture(ctx.TEXTURE_2D, texture);
+ ctx.pixelStorei( ctx.UNPACK_FLIP_Y_WEBGL, false );
+ ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA, ctx.RGBA, ctx.UNSIGNED_BYTE, image);
+ ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.NEAREST);
+ ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.NEAREST);
+ ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE);
+ ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE);
+
+ ctx.bindTexture(ctx.TEXTURE_2D, null);
+}
+
+function createAudioTexture( ctx, texture )
+{
+ if( ctx==null ) return;
+
+ ctx.bindTexture( ctx.TEXTURE_2D, texture );
+ ctx.texParameteri( ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR );
+ ctx.texParameteri( ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR );
+ ctx.texParameteri( ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE );
+ ctx.texParameteri( ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE) ;
+ ctx.texImage2D( ctx.TEXTURE_2D, 0, ctx.LUMINANCE, 512, 2, 0, ctx.LUMINANCE, ctx.UNSIGNED_BYTE, null);
+ ctx.bindTexture( ctx.TEXTURE_2D, null);
+}
+
+function createKeyboardTexture( ctx, texture )
+{
+ if( ctx==null ) return;
+
+ ctx.bindTexture( ctx.TEXTURE_2D, texture );
+ ctx.texParameteri( ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.NEAREST );
+ ctx.texParameteri( ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.NEAREST );
+ ctx.texParameteri( ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE );
+ ctx.texParameteri( ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE) ;
+ ctx.texImage2D( ctx.TEXTURE_2D, 0, ctx.LUMINANCE, 256, 2, 0, ctx.LUMINANCE, ctx.UNSIGNED_BYTE, null);
+ ctx.bindTexture( ctx.TEXTURE_2D, null);
+}
+
+
+function Effect( ac, gl, xres, yres, callback, obj, forceMuted, forcePaused)
+{
+ this.mAudioContext = ac;
+ this.mNoAudioMessageShowed = false;
+ this.mGLContext = gl;
+ this.mQuadVBO = null;
+ this.mProgram = null;
+ this.mXres = xres;
+ this.mYres = yres;
+ this.mInputs = new Array(4);
+ this.mInputs[0] = null;
+ this.mInputs[1] = null;
+ this.mInputs[2] = null;
+ this.mInputs[3] = null;
+ this.mTextureCallbackFun = callback;
+ this.mTextureCallbackObj = obj;
+ this.mSource = null;
+ this.mForceMuted = forceMuted;
+ this.mForcePaused = forcePaused;
+ this.mSupportsDerivatives = false;
+
+ //-------------
+ if( gl==null ) return;
+
+ var ext = gl.getExtension('OES_standard_derivatives');
+ this.mSupportsDerivatives = (ext != null);
+
+ if( this.mSupportsDerivatives )
+ {
+ gl.hint( ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl.NICEST );
+ }
+
+ var ext2 = gl.getExtension('OES_texture_float');
+ this.mSupportTextureFloat = (ext2 != null );
+
+ var vertices = new Float32Array( [ -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0] );
+
+ this.mQuadVBO = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.mQuadVBO);
+ gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
+
+ var res = this.NewShader(fsSource);
+
+ this.DetermineShaderPrecission();
+
+ this.MakeHeader();
+}
+
+Effect.prototype.DestroyInput = function( id )
+{
+ if( this.mInputs[id]==null ) return;
+ if( this.mGLContext== null ) return;
+
+ var gl = this.mGLContext;
+ if( this.mInputs[id].mInfo.mType=="texture" )
+ {
+ gl.deleteTexture( this.mInputs[id].globject );
+ }
+ else if( this.mInputs[id].mInfo.mType=="slideshow" )
+ {
+ gl.deleteTexture( this.mInputs[id].globject );
+ }
+ else if( this.mInputs[id].mInfo.mType=="webcam" )
+ {
+ gl.deleteTexture( this.mInputs[id].globject );
+ }
+ else if( this.mInputs[id].mInfo.mType=="video" )
+ {
+ this.mInputs[id].video.pause();
+ this.mInputs[id].video = null;
+ gl.deleteTexture( this.mInputs[id].globject );
+ }
+ else if( this.mInputs[id].mInfo.mType=="music" )
+ {
+ this.mInputs[id].audio.pause();
+ this.mInputs[id].audio = null;
+ gl.deleteTexture( this.mInputs[id].globject );
+ }
+ else if( this.mInputs[id].mInfo.mType=="cubemap" )
+ {
+ gl.deleteTexture( this.mInputs[id].globject );
+ }
+ else if( this.mInputs[id].mInfo.mType=="keyboard" )
+ {
+ gl.deleteTexture( this.mInputs[id].globject );
+ }
+
+ this.mInputs[id] = null;
+}
+
+
+
+Effect.prototype.NewTexture = function( slot, url )
+{
+ var me = this;
+ var gl = this.mGLContext;
+
+ var texture = null;
+
+ if (url!=null && url.mType=="webcam" && this.mForceMuted)
+ {
+ url.mType = "texture";
+ }
+
+ if( url==null )
+ {
+ if( me.mTextureCallbackFun!=null )
+ me.mTextureCallbackFun( this.mTextureCallbackObj, slot, null, false, true, 0, -1.0 );
+ return false;
+ }
+ else if( url.mType=="texture" )
+ {
+ texture = {};
+ texture.mInfo = url;
+ texture.globject = (gl!=null) ? gl.createTexture() : null;
+ texture.loaded = false;
+ texture.image = new Image();
+ texture.image.crossOrigin = '';
+ texture.image.onload = function()
+ {
+ var format = gl.RGBA;
+ if( url.mSrc=="/presets/tex15.png" || url.mSrc=="/presets/tex17.png" )
+ format = gl.LUMINANCE;
+
+ if( url.mSrc=="/presets/tex14.png" )
+ createGLTextureNearest( gl, texture.image, texture.globject );
+ else if( url.mSrc=="/presets/tex15.png" )
+ createGLTextureNearestRepeat( gl, texture.image, texture.globject );
+ else
+ createGLTexture( gl, texture.image, format, texture.globject );
+
+ texture.loaded = true;
+ if( me.mTextureCallbackFun!=null )
+ me.mTextureCallbackFun( me.mTextureCallbackObj, slot, texture.image, true, true, 0, -1.0 );
+ }
+ texture.image.src = url.mSrc;
+ }
+ else if( url.mType=="slideshow" )
+ {
+ texture = {};
+ texture.mInfo = url;
+ texture.globject = (gl!=null) ? gl.createTexture() : null;
+ texture.loaded = false;
+ texture.image = new Image();
+ texture.image.crossOrigin = '';
+ texture.image.onload = function()
+ {
+ createGLTexture( gl, texture.image, gl.RGBA, texture.globject );
+ texture.loaded = true;
+ if( me.mTextureCallbackFun!=null )
+ me.mTextureCallbackFun( me.mTextureCallbackObj, slot, texture.image, true, true, 3, -1.0 );
+ }
+ texture.slideshow = {};
+ texture.slideshow.mCurrentSlide = 0;
+ texture.slideshow.mNewTextureReady = false;
+ var urlSlide = url.mSrc.replace("??","00");
+ texture.image.src = urlSlide;
+ }
+ else if( url.mType=="cubemap" )
+ {
+ texture = {};
+ texture.mInfo = url;
+ texture.globject = (gl!=null) ? gl.createTexture() : null;
+ texture.loaded = false;
+ texture.image = [ new Image(), new Image(), new Image(), new Image(), new Image(), new Image() ];
+
+ gl.bindTexture( gl.TEXTURE_CUBE_MAP, texture.globject );
+ gl.texParameteri( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR );
+ gl.texParameteri( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR );
+ gl.bindTexture( gl.TEXTURE_CUBE_MAP, null );
+
+ texture.loaded = true;
+
+ for( var i=0; i<6; i++ )
+ {
+ texture.image[i].mId = i;
+ texture.image[i].crossOrigin = '';
+ texture.image[i].onload = function()
+ {
+ var id = this.mId;
+ gl.bindTexture( gl.TEXTURE_CUBE_MAP, texture.globject );
+ gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, false );
+ gl.texImage2D( gl.TEXTURE_CUBE_MAP_POSITIVE_X + id, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image[id] );
+ gl.bindTexture( gl.TEXTURE_CUBE_MAP, null );
+ if( me.mTextureCallbackFun!=null )
+ me.mTextureCallbackFun( me.mTextureCallbackObj, slot, texture.image[0], true, true, 0, -1.0 );
+ }
+
+ texture.image[i].src = url.mSrc.replace( "_0.", "_" + i + "." );
+ }
+ }
+ else if( url.mType=="webcam" )
+ {
+ texture = {};
+ texture.mInfo = url;
+ texture.globject = null;
+ texture.loaded = false;
+
+ texture.video = document.createElement('video');
+ texture.video.width = 320;
+ texture.video.height = 240;
+ texture.video.autoplay = true;
+ texture.video.loop = true;
+ texture.video.paused = true;
+
+ navigator.getUserMedia( { "video": true, "audio": false },
+ function(stream)
+ {
+ texture.video.src = window.URL.createObjectURL(stream);
+
+ texture.globject = gl.createTexture();
+ try
+ {
+ createGLTextureLinear( gl, texture.video, texture.globject );
+ texture.loaded = true;
+ }
+ catch(e)
+ {
+ alert( 'Your browser can not transfer webcam data to the GPU.');
+ }
+ },
+ function(error)
+ {
+ alert( 'Unable to capture WebCam. Please reload the page.' );
+ } );
+ }
+ else if( url.mType=="video" )
+ {
+ texture = {};
+ texture.mInfo = url;
+ texture.globject = null;
+ texture.loaded = false;
+ texture.video = document.createElement('video');
+ texture.video.width = 256;
+ texture.video.height = 256;
+ texture.video.loop = true;
+ texture.video.paused = true;//this.mForcePaused;
+ texture.video.mPaused = true;//this.mForcePaused;
+ texture.video.mMuted = this.mForceMuted;
+ texture.video.muted = this.mForceMuted;
+ if( this.mForceMuted==true )
+ texture.video.volume = 0;
+ texture.video.autoplay = false;
+ texture.video.hasFalled = false;
+
+ texture.video.addEventListener( "canplay", function(e)
+ {
+ texture.video.play();
+ texture.video.paused = false;
+ texture.video.mPaused = false;
+
+ texture.globject = gl.createTexture();
+ createGLTextureLinear( gl, texture.video, texture.globject );
+ texture.loaded = true;
+
+ if( me.mTextureCallbackFun!=null )
+ me.mTextureCallbackFun( me.mTextureCallbackObj, slot, texture.video, true, true, 1, -1.0 );
+
+ } );
+
+ texture.video.addEventListener( "error", function(e)
+ {
+ if( texture.video.hasFalled==true ) { alert("Error: cannot load video" ); return; }
+ var str = texture.video.src;
+ str = str.substr(0,str.lastIndexOf('.') ) + ".mp4";
+ texture.video.src = str;
+ texture.video.hasFalled = true;
+ } );
+
+
+ texture.video.src = url.mSrc;
+ }
+ else if( url.mType=="music" )
+ {
+ texture = {};
+ texture.mInfo = url;
+ texture.globject = null;
+ texture.loaded = false;
+ texture.audio = document.createElement('audio');
+ texture.audio.loop = true;
+ texture.audio.mMuted = this.mForceMuted;
+ texture.audio.mForceMuted = this.mForceMuted;
+
+ texture.audio.muted = this.mForceMuted;
+ if( this.mForceMuted==true )
+ texture.audio.volume = 0;
+ texture.audio.autoplay = true;
+ texture.audio.hasFalled = false;
+ texture.audio.paused = true;
+ texture.audio.mPaused = true;
+ texture.audio.mSound = {};
+
+ if( this.mForceMuted )
+ {
+ texture.globject = gl.createTexture();
+ createAudioTexture( gl, texture.globject );
+ var num = 512;
+ texture.audio.mSound.mFreqData = new Uint8Array( num );
+ texture.audio.mSound.mWaveData = new Uint8Array( num );
+ texture.loaded = true;
+ texture.audio.paused = false;
+ texture.audio.mPaused = false;
+ }
+
+ texture.audio.addEventListener( "canplay", function()
+ {
+ if( this.mForceMuted ) return;
+
+ texture.globject = gl.createTexture();
+ createAudioTexture( gl, texture.globject );
+
+ if( me.mAudioContext != null )
+ {
+ var ctx = me.mAudioContext;
+ texture.audio.mSound.mSource = ctx.createMediaElementSource( texture.audio );
+ texture.audio.mSound.mAnalyser = ctx.createAnalyser();
+ texture.audio.mSound.mGain = ctx.createGain();
+
+ texture.audio.mSound.mSource.connect( texture.audio.mSound.mAnalyser );
+ texture.audio.mSound.mAnalyser.connect( texture.audio.mSound.mGain );
+ texture.audio.mSound.mGain.connect( ctx.destination );
+
+ texture.audio.mSound.mFreqData = new Uint8Array( texture.audio.mSound.mAnalyser.frequencyBinCount );
+ texture.audio.mSound.mWaveData = new Uint8Array( texture.audio.mSound.mAnalyser.frequencyBinCount );
+
+ texture.loaded = true;
+ texture.audio.paused = false;
+ texture.audio.mPaused = false;
+ }
+ else
+ {
+ if( me.mNoAudioMessageShowed==false )
+ {
+ var ve = document.getElementById( "centerScreen" );
+ doAlert( getCoords(ve), {mX:420,mY:160}, "Error", "Your browser does not support WebAudio.
This shader will not work as the author intended. Please consider using a WebAudio-friendly browser (Chrome).", false, null );
+ me.mNoAudioMessageShowed = true;
+ }
+ }
+ } );
+
+ texture.audio.addEventListener( "error", function(e)
+ {
+ if( this.mForceMuted ) return;
+
+ if( texture.audio.hasFalled==true ) { /*alert("Error: cannot load music" ); */return; }
+ var str = texture.audio.src;
+ str = str.substr(0,str.lastIndexOf('.') ) + ".ogg";
+ texture.audio.src = str;
+ texture.audio.hasFalled = true;
+ } );
+
+ if( !this.mForceMuted )
+ {
+ texture.audio.src = url.mSrc;
+ }
+
+
+ if( me.mTextureCallbackFun!=null )
+ me.mTextureCallbackFun( me.mTextureCallbackObj, slot, null, false, true, 2, -1.0 );
+ }
+ else if( url.mType=="keyboard" )
+ {
+ texture = {};
+ texture.mInfo = url;
+ texture.globject = gl.createTexture();
+ texture.loaded = true;
+
+ texture.keyboard = {};
+
+ texture.keyboard.mImage = new Image();
+ texture.keyboard.mImage.onload = function()
+ {
+ texture.loaded = true;
+ if( me.mTextureCallbackFun!=null )
+ me.mTextureCallbackFun( me.mTextureCallbackObj, slot, {mImage:texture.keyboard.mImage,mData:texture.keyboard.mData}, false, false, 4, -1.0 );
+ }
+ texture.keyboard.mImage.src = "/img/keyboard.png";
+
+
+ texture.keyboard.mNewTextureReady = true;
+ texture.keyboard.mData = new Uint8Array( 256*2 );
+
+ createKeyboardTexture( gl, texture.globject );
+
+ for( var j=0; j<(256*2); j++ )
+ {
+ texture.keyboard.mData[j] = 0;
+ }
+
+ if( me.mTextureCallbackFun!=null )
+ me.mTextureCallbackFun( me.mTextureCallbackObj, slot, {mImage:texture.keyboard.mImage,mData:texture.keyboard.mData}, false, false, 4, -1.0 );
+ }
+ else if( url.mType==null )
+ {
+ if( me.mTextureCallbackFun!=null )
+ me.mTextureCallbackFun( this.mTextureCallbackObj, slot, null, false, true, 0, -1.0 );
+ }
+ else
+ {
+ alert( "texture type error" );
+ return;
+ }
+
+ this.DestroyInput( slot );
+ this.mInputs[slot] = texture;
+
+ this.MakeHeader();
+}
+
+Effect.prototype.SetKeyDown = function( k )
+{
+ for( var i=0; i1 )
+ {
+ return { mFailed : true, mError : "ShaderToy only supports one-pass shaders at this momment", mShader:null };
+ }
+ for( var j=0; j x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);",
+ "vec4 x12 = x0.xyxy + C.xxzz;",
+ "x12.xy -= i1;",
+
+ "i = mod289(i); // Avoid truncation effects in permutation",
+ "vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))",
+ "+ i.x + vec3(0.0, i1.x, 1.0 ));",
+
+ "vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);",
+ "m = m*m ;",
+ "m = m*m ;",
+
+ "vec3 x = 2.0 * fract(p * C.www) - 1.0;",
+ "vec3 h = abs(x) - 0.5;",
+ "vec3 ox = floor(x + 0.5);",
+ "vec3 a0 = x - ox;",
+
+ "m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );",
+
+ "vec3 g;",
+ "g.x = a0.x * x0.x + h.x * x0.y;",
+ "g.yz = a0.yz * x12.xz + h.yz * x12.yw;",
+
+ "return 130.0 * dot(m, g);",
+ "}",
+
+ "float fbm(vec2 p) {",
+ "float f = 0.0;",
+ "float w = 0.5;",
+ "for (int i = 0; i < 5; i ++) {",
+ "f += w * snoise(p);",
+ "p *= 2.;",
+ "w *= 0.5;",
+ "}",
+ "return f;",
+ "}",
+
+
+ "vec4 tunneliter(vec2 texCoord,vec4 incol,float cx,float cy,float limita,float limitb,vec4 coloz,float tadd)",
+ "{",
+ "vec2 texc;",
+ "vec2 tex;",
+ "vec4 outCol;",
+ "float disty;",
+
+ "texc=(texCoord-vec2(cx,cy));",
+ "disty=distance(texc,vec2(0.0,0.0));",
+ "tex.x=(abs(atan(texc.x,texc.y)))/6.2830;",
+ "tex.y=0.5/disty;",
+ "tex.y+=(iGlobalTime*0.9)+tadd;",
+
+ "float fbmval=abs(fbm(tex));",
+
+ "float bex=mix(fbmval,1.0,smoothstep(limitb,limita,disty))*smoothstep(limitb,limita,disty);",
+ "outCol=mix(incol,coloz*(1.0-fbmval),bex);",
+
+ "return outCol;",
+ "}",
+
+ "void main(void)",
+ "{",
+ "vec2 uv = gl_FragCoord.xy / iResolution.xy;",
+ "gl_FragColor = vec4(uv,0.5+0.5*sin(iGlobalTime),1.0);",
+
+ "vec4 finalCol;",
+
+ "float xa=(sin(iGlobalTime)*0.4)+(sin((iGlobalTime*1.3)+0.5)*0.24);",
+ "float ya=(cos(iGlobalTime)*0.45)+(cos((iGlobalTime*0.6)-0.7)*0.3);",
+
+ "finalCol=vec4(1.0,0.0,1.0,1.0);",
+
+ "finalCol=tunneliter(uv,vec4(1.0,1.0,1.0,1.0),0.5+(xa*0.80),0.5+(ya*0.80),0.04,0.01,vec4(0.9,0.9,1.0,1.0),3.1);",
+ "finalCol=tunneliter(uv,finalCol,0.5+(xa*0.90),0.5+(ya*0.70),0.08,0.03,vec4(0.7,0.7,0.8,1.0),7.2);",
+ "finalCol=tunneliter(uv,finalCol,0.5+(xa*0.70),0.5+(ya*0.70),0.14,0.05,vec4(0.6,0.6,0.7,1.0),9.3);",
+ "finalCol=tunneliter(uv,finalCol,0.5+(xa*0.58),0.5+(ya*0.58),0.18,0.10,vec4(0.5,0.5,0.6,1.0),4.4);",
+ "finalCol=tunneliter(uv,finalCol,0.5+(xa*0.35),0.5+(ya*0.35),0.24,0.15,vec4(0.4,0.4,0.5,1.0),2.5);",
+ "finalCol=tunneliter(uv,finalCol,0.5+(xa*0.22),0.5+(ya*0.22),0.30,0.20,vec4(0.4,0.4,0.5,1.0),9.6);",
+ "finalCol=tunneliter(uv,finalCol,0.5+(xa*0.15),0.5+(ya*0.15),0.40,0.25,vec4(0.3,0.3,0.4,1.0),6.7);",
+ "finalCol=tunneliter(uv,finalCol,0.5+(xa*0.12),0.5+(ya*0.12),0.50,0.35,vec4(0.3,0.3,0.4,1.0),3.8);",
+ "finalCol=tunneliter(uv,finalCol,0.5+(xa*0.10),0.5+(ya*0.10),0.60,0.40,vec4(0.3,0.3,0.4,1.0),7.9);",
+
+ "gl_FragColor = vec4(vec3(finalCol.xyz),1.0);",
+
+ "}"];
+
+}
+
+PIXI.SoftTunnelFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.SoftTunnelFilter.prototype.constructor = PIXI.SoftTunnelFilter;
+
+Object.defineProperty(PIXI.SoftTunnelFilter.prototype, 'iGlobalTime', {
+ get: function() {
+ return this.uniforms.iGlobalTime.value;
+ },
+ set: function(value) {
+ this.uniforms.iGlobalTime.value = value;
+ }
+});
+
+var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('texture', 'wip/tex15.png');
+
+}
+
+var filter;
+var sprite;
+
+function create() {
+
+ sprite = game.add.sprite(0, 0, 'texture');
+ sprite.width = 800;
+ sprite.height = 600;
+
+ filter = new PIXI.SoftTunnelFilter(sprite.width, sprite.height, sprite.texture);
+
+ sprite.filters = [filter];
+
+}
+
+function update() {
+
+ filter.iGlobalTime = game.time.totalElapsedSeconds();
+
+}
+
+function render() {
+}
diff --git a/examples/wip/starNurseryFilter.js b/examples/wip/starNurseryFilter.js
index 712251a6..dc7699fd 100644
--- a/examples/wip/starNurseryFilter.js
+++ b/examples/wip/starNurseryFilter.js
@@ -17,7 +17,7 @@ PIXI.StarNurseryFilter = function(width, height, texture)
iResolution: { type: 'f3', value: { x: width, y: height, z: 0 }},
iGlobalTime: { type: 'f', value: 1 },
iDate: { type: 'f4', value: dates },
- iChannel0: { type: 'sampler2D', value: texture }
+ iChannel0: { type: 'sampler2D', value: texture, wrap: 'repeat' }
};
// Shader by Dave Hoskins (https://www.shadertoy.com/view/XsfGzH)
@@ -206,7 +206,7 @@ var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: p
function preload() {
// game.load.image('texture', 'wip/64x64.png');
- game.load.image('texture', 'wip/tex16.png');
+ game.load.image('texture', 'wip/tex12.png');
}
diff --git a/examples/wip/starfieldFilter.js b/examples/wip/starfieldFilter.js
index 10c851cb..e1d22f80 100644
--- a/examples/wip/starfieldFilter.js
+++ b/examples/wip/starfieldFilter.js
@@ -17,7 +17,7 @@ PIXI.StarFieldFilter = function(width, height, texture)
iResolution: { type: 'f3', value: { x: width, y: height, z: 0 }},
iGlobalTime: { type: 'f', value: 1 },
iDate: { type: 'f4', value: dates },
- iChannel0: { type: 'sampler2D', value: texture }
+ iChannel0: { type: 'sampler2D', value: texture, wrap: 'repeat' }
};
// Shader by Rebb / TRSI (https://www.shadertoy.com/view/XdX3Wn)
@@ -125,8 +125,8 @@ var sprite;
function create() {
sprite = game.add.sprite(0, 0, 'texture');
- sprite.width = 512;
- sprite.height = 512;
+ sprite.width = 800;
+ sprite.height = 600;
filter = new PIXI.StarFieldFilter(sprite.width, sprite.height, sprite.texture);
diff --git a/examples/wip/tunnelFilter.js b/examples/wip/tunnelFilter.js
new file mode 100644
index 00000000..4d0340e8
--- /dev/null
+++ b/examples/wip/tunnelFilter.js
@@ -0,0 +1,157 @@
+PIXI.TunnelFilter = function(width, height, texture)
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ var d = new Date();
+
+ var dates = [
+ d.getFullYear(), // the year (four digits)
+ d.getMonth(), // the month (from 0-11)
+ d.getDate(), // the day of the month (from 1-31)
+ d.getHours()*60.0*60 + d.getMinutes()*60 + d.getSeconds()
+ ];
+
+ this.uniforms = {
+ iResolution: { type: 'f3', value: { x: width, y: height, z: 0 }},
+ iGlobalTime: { type: 'f', value: 1 },
+ iDate: { type: 'f4', value: dates },
+ iChannel0: { type: 'sampler2D', value: texture, wrap: 'nearest-repeat' }
+ };
+
+ // Shader by reiska (https://www.shadertoy.com/view/4sX3z7)
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "uniform vec3 iResolution;",
+ "uniform float iGlobalTime;",
+ "uniform float iChannelTime[4];",
+ "uniform vec4 iMouse;",
+ "uniform vec4 iDate;",
+ "uniform vec3 iChannelResolution[4];",
+ "uniform sampler2D iChannel0;",
+ "// add any extra uniforms here",
+
+ "void main(void)",
+ "{",
+ "float cameraPinch = 1.0; // values between 0 - 2, this will modify (pinch) the view",
+ "float cameraZPinch = 1.0; //",
+ "float cameraZFactor = 1.0; // 0-1",
+ "float zoomFactor = 1.0; // large values will create a kaleidoscopic effect!",
+
+ "float texCoordUScale = 0.125;",
+ "float texCoordVScale = 1.0;",
+
+ "float texCoordUMoveSpeed = 0.20;",
+ "float texCoordVMoveSpeed = -0.125;",
+
+ "float cameraRotationSpeed = 0.5; // 0.0 to switch off rotation (look straight ahead)",
+
+ "float tunnelPinch = 2.0; // 1.0 = round tunnel, change the value to modify the shape",
+
+ "float spikeCount = 5.0;",
+ "float spikeFactor = sin(iGlobalTime) * 0.1; // 0.0 to switch off spikes",
+
+ "vec3 fogColor = vec3(0.0, 0.0, 0.0);",
+ "float fogPower = 10.0;",
+
+ "vec2 coord = 2.0 * ((gl_FragCoord.xy / iResolution.xy) - vec2(0.5, 0.5));",
+
+ "float aspectRatio = iResolution.x / iResolution.y;",
+
+ "coord.x *= aspectRatio;",
+ "coord *= zoomFactor;",
+
+ "coord = vec2(sign(coord.x) * pow(abs(coord.x), cameraPinch), sign(coord.y) * pow(abs(coord.y), cameraPinch));",
+
+ "// camera angles",
+ "float camAng = iGlobalTime * cameraRotationSpeed;",
+
+ "// camera rotation vectors",
+ "vec3 cx = vec3(cos(camAng), 0.0, -sin(camAng));",
+ "vec3 cy = vec3(0.0, 1.0, 0.0);",
+ "vec3 cz = vec3(sin(camAng), 0.0, cos(camAng));",
+
+ "mat3 cameraRot =",
+ "mat3(",
+ "cx.x, cx.y, cx.z,",
+ "cy.x, cy.y, cy.z,",
+ "cz.x, cz.y, cz.z);",
+
+ "vec3 cameraDir = normalize(vec3(sin(coord.x), sin(coord.y), cos(coord.x) * cos(coord.y)));",
+
+ "cameraDir = cameraRot * cameraDir;",
+
+ "float angle = atan(cameraDir.x, cameraDir.y);",
+ "cameraDir.z *= 1.0 + sin(angle * spikeCount) * spikeFactor;",
+
+ "cameraDir.z = cameraZFactor * sign(cameraDir.z) * pow(abs(cameraDir.z), cameraZPinch);",
+
+
+ "vec3 cameraOrigin = vec3(0.0, 0.0, 0.0);",
+
+ "float l = sqrt(pow(cameraDir.x * cameraDir.x, tunnelPinch) + pow(cameraDir.y * cameraDir.y, tunnelPinch));",
+ "float d = 1.0 / l;",
+
+ "vec3 hitPos = cameraOrigin + cameraDir * d;",
+
+
+ "vec2 uv = vec2(hitPos.z, angle / 3.14159);",
+ "uv.x = uv.x * texCoordUScale + iGlobalTime * texCoordUMoveSpeed;",
+ "uv.y = uv.y * texCoordVScale + iGlobalTime * texCoordVMoveSpeed;",
+ "vec3 color = texture2D(iChannel0, uv).rgb;",
+
+ "float alpha = 1.0 - pow(min(1.0, abs(cameraDir.z)), fogPower);",
+
+ "color = fogColor * (1.0 - alpha) + color * alpha;",
+
+ "gl_FragColor = vec4(color, 1.0);",
+ "}"];
+
+
+
+}
+
+PIXI.TunnelFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.TunnelFilter.prototype.constructor = PIXI.TunnelFilter;
+
+Object.defineProperty(PIXI.TunnelFilter.prototype, 'iGlobalTime', {
+ get: function() {
+ return this.uniforms.iGlobalTime.value;
+ },
+ set: function(value) {
+ this.uniforms.iGlobalTime.value = value;
+ }
+});
+
+var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('texture', 'wip/tex15.png');
+
+}
+
+var filter;
+var sprite;
+
+function create() {
+
+ sprite = game.add.sprite(0, 0, 'texture');
+ sprite.width = 800;
+ sprite.height = 600;
+
+ filter = new PIXI.TunnelFilter(sprite.width, sprite.height, sprite.texture);
+
+ sprite.filters = [filter];
+
+}
+
+function update() {
+
+ filter.iGlobalTime = game.time.totalElapsedSeconds();
+
+}
+
+function render() {
+}
diff --git a/examples/wip/vortexFilter.js b/examples/wip/vortexFilter.js
new file mode 100644
index 00000000..e8806816
--- /dev/null
+++ b/examples/wip/vortexFilter.js
@@ -0,0 +1,111 @@
+PIXI.VortexFilter = function(width, height, texture)
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ var d = new Date();
+
+ var dates = [
+ d.getFullYear(), // the year (four digits)
+ d.getMonth(), // the month (from 0-11)
+ d.getDate(), // the day of the month (from 1-31)
+ d.getHours()*60.0*60 + d.getMinutes()*60 + d.getSeconds()
+ ];
+
+ this.uniforms = {
+ iResolution: { type: 'f3', value: { x: width, y: height, z: 0 }},
+ iGlobalTime: { type: 'f', value: 1 },
+ iDate: { type: 'f4', value: dates },
+ iChannel0: { type: 'sampler2D', value: texture, wrap: 'repeat' }
+ };
+
+ // Shader by GhettoWolf (https://www.shadertoy.com/view/Xdl3WH)
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "uniform vec3 iResolution;",
+ "uniform float iGlobalTime;",
+ "uniform float iChannelTime[4];",
+ "uniform vec4 iMouse;",
+ "uniform vec4 iDate;",
+ "uniform vec3 iChannelResolution[4];",
+ "uniform sampler2D iChannel0;",
+ "// add any extra uniforms here",
+
+ "#ifdef GL_ES",
+ "precision highp float;",
+ "#endif",
+
+ "#define PI 3.1416",
+
+ "void main(void)",
+ "{",
+ "//map the xy pixel co-ordinates to be between -1.0 to +1.0 on x and y axes",
+ "//and alter the x value according to the aspect ratio so it isn't 'stretched'",
+ "vec2 p = (2.0 * gl_FragCoord.xy / iResolution.xy - 1.0)",
+ "* vec2(iResolution.x / iResolution.y, 1.0);",
+
+ "//now, this is the usual part that uses the formula for texture mapping a ray-",
+ "//traced cylinder using the vector p that describes the position of the pixel",
+ "//from the centre.",
+ "vec2 uv = vec2(atan(p.y, p.x) * 1.0/PI, 1.0 / sqrt(dot(p, p))) * vec2(2.0, 1.0);",
+
+
+ "//now this just 'warps' the texture read by altering the u coordinate depending on",
+ "//the val of the v coordinate and the current time",
+ "uv.x += sin(2.0 * uv.y + iGlobalTime * 0.5);",
+
+ "vec3 c = texture2D(iChannel0, uv).xyz",
+
+ "//this divison makes the color value 'darker' into the distance, otherwise",
+ "//everything will be a uniform brightness and no sense of depth will be present.",
+ "/ (uv.y * 0.5 + 1.0);",
+
+ "gl_FragColor = vec4(c, 1.0);",
+ "}"];
+
+}
+
+PIXI.VortexFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.VortexFilter.prototype.constructor = PIXI.VortexFilter;
+
+Object.defineProperty(PIXI.VortexFilter.prototype, 'iGlobalTime', {
+ get: function() {
+ return this.uniforms.iGlobalTime.value;
+ },
+ set: function(value) {
+ this.uniforms.iGlobalTime.value = value;
+ }
+});
+
+var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('texture', 'wip/tex00.jpg');
+
+}
+
+var filter;
+var sprite;
+
+function create() {
+
+ sprite = game.add.sprite(0, 0, 'texture');
+ sprite.width = 800;
+ sprite.height = 600;
+
+ filter = new PIXI.VortexFilter(sprite.width, sprite.height, sprite.texture);
+
+ sprite.filters = [filter];
+
+}
+
+function update() {
+
+ filter.iGlobalTime = game.time.totalElapsedSeconds();
+
+}
+
+function render() {
+}
diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js
index c729238b..769edaaf 100644
--- a/src/pixi/renderers/webgl/PixiShader.js
+++ b/src/pixi/renderers/webgl/PixiShader.js
@@ -107,22 +107,18 @@ PIXI.PixiShader.prototype.syncUniforms = function()
}
if(type == "f2")
{
- // console.log(this.program[key])
gl.uniform2f(this.uniforms[key].uniformLocation, this.uniforms[key].value.x, this.uniforms[key].value.y);
}
else if(type == "f3")
{
- // console.log(this.uniforms[key].value)
gl.uniform3f(this.uniforms[key].uniformLocation, this.uniforms[key].value.x, this.uniforms[key].value.y, this.uniforms[key].value.z);
}
else if(type == "f3v")
{
- // console.log(this.uniforms[key].value)
gl.uniform3fv(this.uniforms[key].uniformLocation, this.uniforms[key].value);
}
else if(type == "f4")
{
- // console.log(this.uniforms[key].value)
gl.uniform4fv(this.uniforms[key].uniformLocation, this.uniforms[key].value);
}
else if(type == "mat4")
@@ -131,13 +127,50 @@ PIXI.PixiShader.prototype.syncUniforms = function()
}
else if(type == "sampler2D")
{
- // first texture...
- var texture = this.uniforms[key].value;
-
- gl.activeTexture(gl.TEXTURE1);
- gl.bindTexture(gl.TEXTURE_2D, texture.baseTexture._glTexture);
-
- gl.uniform1i(this.uniforms[key].uniformLocation, 1);
+ var texture = this.uniforms[key].value.baseTexture._glTexture;
+ var image = this.uniforms[key].value.baseTexture.source;
+ var format = gl.RGBA;
+
+ if (this.uniforms[key].format && this.uniforms[key].format == 'luminance')
+ {
+ format = gl.LUMINANCE;
+ }
+
+ gl.activeTexture(gl.TEXTURE1);
+
+ if (this.uniforms[key].wrap)
+ {
+ if (this.uniforms[key].wrap == 'no-repeat' || this.uniforms[key].wrap === false)
+ {
+ this.createGLTextureLinear(gl, image, texture);
+ }
+ else if (this.uniforms[key].wrap == 'repeat' || this.uniforms[key].wrap === true)
+ {
+ this.createGLTexture(gl, image, format, texture);
+ }
+ else if (this.uniforms[key].wrap == 'nearest-repeat')
+ {
+ this.createGLTextureNearestRepeat(gl, image, texture);
+ }
+ else if (this.uniforms[key].wrap == 'nearest')
+ {
+ this.createGLTextureNearest(gl, image, texture);
+ }
+ else if (this.uniforms[key].wrap == 'audio')
+ {
+ this.createAudioTexture(gl, texture);
+ }
+ else if (this.uniforms[key].wrap == 'keyboard')
+ {
+ this.createKeyboardTexture(gl, texture);
+ }
+ }
+ else
+ {
+ this.createGLTextureLinear(gl, image, texture);
+ }
+
+ gl.uniform1i(this.uniforms[key].uniformLocation, 1);
// activate texture..
// gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value);
@@ -145,6 +178,71 @@ PIXI.PixiShader.prototype.syncUniforms = function()
}
}
+};
+
+PIXI.PixiShader.prototype.createGLTexture = function(gl, image, format, texture)
+{
+ gl.bindTexture( gl.TEXTURE_2D, texture);
+ gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D( gl.TEXTURE_2D, 0, format, gl.RGBA, gl.UNSIGNED_BYTE, image);
+ gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
+ gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
+ gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+ gl.generateMipmap(gl.TEXTURE_2D);
+}
+
+PIXI.PixiShader.prototype.createGLTextureLinear = function(gl, image, texture)
+{
+ gl.bindTexture( gl.TEXTURE_2D, texture);
+ gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+}
+
+PIXI.PixiShader.prototype.createGLTextureNearestRepeat = function(gl, image, texture)
+{
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+}
+
+PIXI.PixiShader.prototype.createGLTextureNearest = function(gl, image, texture)
+{
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+}
+
+PIXI.PixiShader.prototype.createAudioTexture = function(gl, texture)
+{
+ gl.bindTexture( gl.TEXTURE_2D, texture );
+ gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR );
+ gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR );
+ gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );
+ gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) ;
+ gl.texImage2D( gl.TEXTURE_2D, 0, gl.LUMINANCE, 512, 2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, null);
+}
+
+PIXI.PixiShader.prototype.createKeyboardTexture = function(gl, texture)
+{
+ gl.bindTexture( gl.TEXTURE_2D, texture );
+ gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
+ gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
+ gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );
+ gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) ;
+ gl.texImage2D( gl.TEXTURE_2D, 0, gl.LUMINANCE, 256, 2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, null);
}
PIXI.PixiShader.defaultVertexSrc = [