diff --git a/examples/wip/binarySerpentsFilter.js b/examples/wip/binarySerpentsFilter.js new file mode 100644 index 000000000..bb12c1f66 --- /dev/null +++ b/examples/wip/binarySerpentsFilter.js @@ -0,0 +1,130 @@ +PIXI.BinarySerpentsFilter = 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 }}, + iMouse: { type: 'f3', value: { x: 0, y: 0, z: 0 }}, + iGlobalTime: { type: 'f', value: 1 }, + iDate: { type: 'f4', value: dates }, + iChannel0: { type: 'sampler2D', value: texture, wrap: 'repeat' } + }; + + // Shader by Trisomie21 (https://www.shadertoy.com/view/MslGRH) + 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", + + "// With tweaks by PauloFalcao", + + "float Texture3D(vec3 n, float res){", + "n = floor(n*res+.5);", + "return fract(sin((n.x+n.y*1e5+n.z*1e7)*1e-4)*1e5);", + "}", + + "float map( vec3 p ){", + "p.x+=sin(p.z*4.0+iGlobalTime*4.0)*0.1*cos(iGlobalTime*0.1);", + "p = mod(p,vec3(1.0, 1.0, 1.0))-0.5;", + "return length(p.xy)-.1;", + "}", + + "void main( void )", + "{", + "vec2 pos = (gl_FragCoord.xy*2.0 - iResolution.xy) / iResolution.y;", + "vec3 camPos = vec3(cos(iGlobalTime*0.3), sin(iGlobalTime*0.3), 1.5);", + "vec3 camTarget = vec3(0.0, 0.0, 0.0);", + + "vec3 camDir = normalize(camTarget-camPos);", + "vec3 camUp = normalize(vec3(0.0, 1.0, 0.0));", + "vec3 camSide = cross(camDir, camUp);", + "float focus = 2.0;", + + "vec3 rayDir = normalize(camSide*pos.x + camUp*pos.y + camDir*focus);", + "vec3 ray = camPos;", + "float d = 0.0, total_d = 0.0;", + "const int MAX_MARCH = 100;", + "const float MAX_DISTANCE = 5.0;", + "float c = 1.0;", + "for(int i=0; iMAX_DISTANCE) { c = 0.; total_d=MAX_DISTANCE; break; }", + "}", + + "float fog = 5.0;", + "vec4 result = vec4( vec3(c*.4 , c*.6, c) * (fog - total_d) / fog, 1.0 );", + + "ray.z -= 5.+iGlobalTime*.5;", + "float r = Texture3D(ray, 33.);", + "gl_FragColor = result*(step(r,.3)+r*.2+.1);", + "}"]; + + + +} + +PIXI.BinarySerpentsFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.BinarySerpentsFilter.prototype.constructor = PIXI.BinarySerpentsFilter; + +Object.defineProperty(PIXI.BinarySerpentsFilter.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/tex01.jpg'); + +} + +var filter; +var sprite; + +function create() { + + sprite = game.add.sprite(0, 0, 'texture'); + sprite.width = 800; + sprite.height = 600; + + filter = new PIXI.BinarySerpentsFilter(sprite.width, sprite.height, sprite.texture); + + sprite.filters = [filter]; + +} + +function update() { + + filter.iGlobalTime = game.time.totalElapsedSeconds(); + filter.uniforms.iMouse.value.x = game.input.x; + filter.uniforms.iMouse.value.y = game.input.y; + +} + +function render() { +} diff --git a/examples/wip/book/fire.js b/examples/wip/book/fire.js new file mode 100644 index 000000000..4cbdc5b25 --- /dev/null +++ b/examples/wip/book/fire.js @@ -0,0 +1,96 @@ +PIXI.FireFilter = 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 = { + resolution: { type: 'f2', value: { x: width, y: height }}, + mouse: { type: 'f2', value: { x: 0, y: 0 }}, + time: { type: 'f', value: 1 } + }; + + // http://glsl.heroku.com/e#11707.0 + + // Heroku shader conversion + this.fragmentSrc = [ + + "#ifdef GL_ES", + "precision mediump float;", + "#endif", + + "uniform float time;", + "uniform vec2 mouse;", + "uniform vec2 resolution;", + + "vec3 iResolution = vec3(resolution.x,resolution.y,100.);", + "vec4 iMouse = vec4(mouse.x,mouse.y,5.,5.);", + "float iGlobalTime = time;", + "uniform sampler2D iChannel0;", + + "// by @301z", + + "float rand(vec2 n) {", + "return fract(cos(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);", + "}", + + "// Genera ruido en función de las coordenadas del pixel", + "float noise(vec2 n) {", + "const vec2 d = vec2(0.0, 1.0);", + "vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n));", + "return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y);", + "}", + + "// Fractional Brownian Amplitude. Suma varias capas de ruido.", + "float fbm(vec2 n) {", + "float total = 0.0, amplitude = 1.0;", + "for (int i = 0; i < 4; i++) {", + "total += noise(n) * amplitude;", + "n += n;", + "amplitude *= 0.5;", + "}", + "return total;", + "}", + + "void main() {", + "// Colores", + "const vec3 c1 = vec3(0.5, 0.0, 0.1); // Rojo oscuro.", + "const vec3 c2 = vec3(0.9, 0.0, 0.0); // Rojo claro.", + "const vec3 c3 = vec3(0.2, 0.0, 0.0); // Rojo oscuro.", + "const vec3 c4 = vec3(1.0, 0.9, 0.0); // Amarillo.", + "const vec3 c5 = vec3(0.1); // Gris oscuro.", + "const vec3 c6 = vec3(0.9); // Gris claro.", + + "vec2 p = gl_FragCoord.xy * 8.0 / iResolution.xx; // Desfasa las coordenadas para que haya más cambio de un resultado a los colindantes.", + "float q = fbm(p - iGlobalTime * 0.1); // Ruido con offset para el movimiento.", + "vec2 r = vec2(fbm(p + q + iGlobalTime * 0.7 - p.x - p.y), fbm(p + q - iGlobalTime * 0.4));", + "vec3 c = mix(c1, c2, fbm(p + r)) + mix(c3, c4, r.x) - mix(c5, c6, r.y);", + "gl_FragColor = vec4(c *", + "cos(1.57 * gl_FragCoord.y / iResolution.y), // Gradiente más ocuro arriba.", + "1.0);", + "}"]; + + + +} + +PIXI.FireFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.FireFilter.prototype.constructor = PIXI.FireFilter; + +Object.defineProperty(PIXI.FireFilter.prototype, 'iGlobalTime', { + get: function() { + return this.uniforms.time.value; + }, + set: function(value) { + this.uniforms.time.value = value; + } +}); diff --git a/examples/wip/book/part2.html b/examples/wip/book/part2.html index 287a840b6..2219255a3 100644 --- a/examples/wip/book/part2.html +++ b/examples/wip/book/part2.html @@ -17,9 +17,115 @@ diff --git a/examples/wip/book/phaser.js b/examples/wip/book/phaser.js index 00f0335ae..11756e35a 100644 --- a/examples/wip/book/phaser.js +++ b/examples/wip/book/phaser.js @@ -18,7 +18,7 @@ * * Phaser - http://www.phaser.io * -* v1.1.3 - Built at: Mon Nov 18 2013 20:26:29 +* v1.1.3 - Built at: Wed Nov 20 2013 06:21:52 * * By Richard Davey http://www.photonstorm.com @photonstorm * @@ -289,19 +289,54 @@ Phaser.Utils = { // Global functions that PIXI needs - /** - * Converts a hex color number to an [R, G, B] array - * - * @param {number} hex - * @return {array} - */ +(function() { + var consoleDisabled = false; + if (consoleDisabled) { + window.console = undefined; + } + if (window.console == undefined) { + window.console = { + debug: function() { + return true; + }, + info: function() { + return false; + }, + warn: function() { + return false; + }, + log: function() { + return false; + } + } + } + debug = (function(args) { + window.console.debug(args); + }); + info = (function(args) { + window.console.info(args); + }); + warn = (function(args) { + window.console.warn(args); + }); + log = (function(args) { + window.console.log(args); + }); +})(); + +/** +* Converts a hex color number to an [R, G, B] array +* +* @param {number} hex +* @return {array} +*/ function HEXtoRGB(hex) { return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255]; } - /** - * A polyfill for Function.prototype.bind - */ +/** +* A polyfill for Function.prototype.bind +*/ if (typeof Function.prototype.bind != 'function') { Function.prototype.bind = (function () { var slice = Array.prototype.slice; @@ -1305,6 +1340,7 @@ PIXI.DisplayObject.prototype.removeFilter = function(data) { //if(!this.filter)return; //this.filter = false; + console.log("YUOIO") // modify the list.. var startBlock = data.start; @@ -4487,7 +4523,7 @@ PIXI.PixiShader.prototype.init = function() var program = PIXI.compileProgram(this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc) var gl = PIXI.gl; - + gl.useProgram(program); // get and store the uniforms for the shader @@ -4525,18 +4561,62 @@ PIXI.PixiShader.prototype.syncUniforms = function() var type = this.uniforms[key].type; // need to grow this! + +/* + http://www.khronos.org/registry/webgl/specs/latest/1.0/ + http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf + + void uniform1f(WebGLUniformLocation? location, GLfloat x); + void uniform1fv(WebGLUniformLocation? location, Float32Array v); + void uniform1fv(WebGLUniformLocation? location, sequence v); + void uniform1i(WebGLUniformLocation? location, GLint x); + void uniform1iv(WebGLUniformLocation? location, Int32Array v); + void uniform1iv(WebGLUniformLocation? location, sequence v); + void uniform2f(WebGLUniformLocation? location, GLfloat x, GLfloat y); + void uniform2fv(WebGLUniformLocation? location, Float32Array v); + void uniform2fv(WebGLUniformLocation? location, sequence v); + void uniform2i(WebGLUniformLocation? location, GLint x, GLint y); + void uniform2iv(WebGLUniformLocation? location, Int32Array v); + void uniform2iv(WebGLUniformLocation? location, sequence v); + void uniform3f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z); + void uniform3fv(WebGLUniformLocation? location, Float32Array v); + void uniform3fv(WebGLUniformLocation? location, sequence v); + void uniform3i(WebGLUniformLocation? location, GLint x, GLint y, GLint z); + void uniform3iv(WebGLUniformLocation? location, Int32Array v); + void uniform3iv(WebGLUniformLocation? location, sequence v); + void uniform4f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void uniform4fv(WebGLUniformLocation? location, Float32Array v); + void uniform4fv(WebGLUniformLocation? location, sequence v); + void uniform4i(WebGLUniformLocation? location, GLint x, GLint y, GLint z, GLint w); + void uniform4iv(WebGLUniformLocation? location, Int32Array v); + void uniform4iv(WebGLUniformLocation? location, sequence v); + + void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value); + void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, sequence value); + void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value); + void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, sequence value); + void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value); + void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, sequence value); +*/ + if(type == "f") { gl.uniform1f(this.uniforms[key].uniformLocation, this.uniforms[key].value); } 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") + { + 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") + { + 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") @@ -4545,13 +4625,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); @@ -4559,6 +4676,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 = [ @@ -6722,6 +6904,7 @@ PIXI.WebGLRenderGroup = function(gl, transparent) this.batchs = []; this.toRemove = []; + console.log(this.transparent) this.filterManager = new PIXI.WebGLFilterManager(this.transparent); } @@ -7821,6 +8004,7 @@ PIXI._CompileShader = function(gl, shaderSrc, shaderType) gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + console.log(gl.getShaderInfoLog(shader)); return null; } @@ -13089,24 +13273,31 @@ Phaser.World.prototype.boot = function () { Phaser.World.prototype.update = function () { this.currentRenderOrderID = 0; - + if (this.game.stage._stage.first._iNext) { var currentNode = this.game.stage._stage.first._iNext; + var skipChildren = false; do { if (currentNode['preUpdate']) { - currentNode.preUpdate(); + skipChildren = (currentNode.preUpdate() == false); } if (currentNode['update']) { - currentNode.update(); + skipChildren = (currentNode.update() == false) || skipChildren; } - currentNode = currentNode._iNext; + if(skipChildren) + { + currentNode = currentNode.last._iNext; + } else { + currentNode = currentNode._iNext; + } + } while (currentNode != this.game.stage._stage.last._iNext) } @@ -18318,7 +18509,14 @@ Phaser.BitmapData = function (game, width, height) { /** * @property {UInt8Clamped} pixels - A reference to the context imageData buffer. */ - this.pixels = this.imageData.data.buffer; + if (this.imageData.data.buffer) + { + this.pixels = this.imageData.data.buffer; + } + else + { + this.pixels = this.imageData.data; + } /** * @property {PIXI.BaseTexture} baseTexture - The PIXI.BaseTexture. @@ -19722,7 +19920,9 @@ Phaser.Sprite.prototype.preUpdate = function() { if (!this.exists || (this.group && !this.group.exists)) { this.renderOrderID = -1; - return; + + // Skip children if not exists + return false; } if (this.lifespan > 0) @@ -19732,7 +19932,7 @@ Phaser.Sprite.prototype.preUpdate = function() { if (this.lifespan <= 0) { this.kill(); - return; + return false; } } @@ -19760,6 +19960,8 @@ Phaser.Sprite.prototype.preUpdate = function() { this.body.preUpdate(); } + return true; + }; /** @@ -22318,6 +22520,16 @@ Phaser.StageScaleMode = function (game, width, height) { */ this.enterPortrait = new Phaser.Signal(); + /** + * @property {Phaser.Signal} enterIncorrectOrientation - The event that is dispatched when the browser enters an incorrect orientation, as defined by forceOrientation. + */ + this.enterIncorrectOrientation = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} leaveIncorrectOrientation - The event that is dispatched when the browser leaves an incorrect orientation, as defined by forceOrientation. + */ + this.leaveIncorrectOrientation = new Phaser.Signal(); + if (window['orientation']) { this.orientation = window['orientation']; @@ -22548,6 +22760,7 @@ Phaser.StageScaleMode.prototype = { // Back to normal this.game.paused = false; this.incorrectOrientation = false; + this.leaveIncorrectOrientation.dispatch(); if (this.orientationSprite) { @@ -22565,6 +22778,7 @@ Phaser.StageScaleMode.prototype = { // Show orientation screen this.game.paused = true; this.incorrectOrientation = true; + this.enterIncorrectOrientation.dispatch(); if (this.orientationSprite && this.orientationSprite.visible == false) { @@ -23016,67 +23230,78 @@ Phaser.Device = function () { */ this.pointerLock = false; + /** + * @property {boolean} typedArray - Does the browser support TypedArrays? + * @default + */ + this.typedArray = false; + // Browser /** - * @property {boolean} arora - Is running in arora? + * @property {boolean} arora - Set to true if running in Arora. * @default */ this.arora = false; /** - * @property {boolean} chrome - Is running in chrome? + * @property {boolean} chrome - Set to true if running in Chrome. * @default */ this.chrome = false; /** - * @property {boolean} epiphany - Is running in epiphany? + * @property {boolean} epiphany - Set to true if running in Epiphany. * @default */ this.epiphany = false; /** - * @property {boolean} firefox - Is running in firefox? + * @property {boolean} firefox - Set to true if running in Firefox. * @default */ this.firefox = false; /** - * @property {boolean} ie - Is running in ie? + * @property {boolean} ie - Set to true if running in Internet Explorer. * @default */ this.ie = false; /** - * @property {number} ieVersion - Version of ie? + * @property {number} ieVersion - If running in Internet Explorer this will contain the major version number. * @default */ this.ieVersion = 0; /** - * @property {boolean} mobileSafari - Is running in mobileSafari? + * @property {boolean} mobileSafari - Set to true if running in Mobile Safari. * @default */ this.mobileSafari = false; /** - * @property {boolean} midori - Is running in midori? + * @property {boolean} midori - Set to true if running in Midori. * @default */ this.midori = false; /** - * @property {boolean} opera - Is running in opera? + * @property {boolean} opera - Set to true if running in Opera. * @default */ this.opera = false; /** - * @property {boolean} safari - Is running in safari? + * @property {boolean} safari - Set to true if running in Safari. * @default */ this.safari = false; + + /** + * @property {boolean} webApp - Set to true if running as a WebApp, i.e. within a WebView + * @default + */ this.webApp = false; // Audio @@ -23116,6 +23341,7 @@ Phaser.Device = function () { * @default */ this.wav = false; + /** * Can this device play m4a files? * @property {boolean} m4a - True if this device can play m4a files. @@ -23343,6 +23569,12 @@ Phaser.Device.prototype = { if (typeof Int8Array !== 'undefined') { this.littleEndian = new Int8Array(new Int16Array([1]).buffer)[0] > 0; + this.typedArray = true; + } + else + { + this.littleEndian = false; + this.typedArray = false; } }, @@ -33214,6 +33446,8 @@ Object.defineProperty(Phaser.Sound.prototype, "volume", { /** * Sound Manager constructor. +* The Sound Manager is responsible for playing back audio via either the Legacy HTML Audio tag or via Web Audio if the browser supports it. +* Note: On Firefox 25+ on Linux if you have media.gstreamer disabled in about:config then it cannot play back mp3 or m4a files. * * @class Phaser.SoundManager * @classdesc Phaser Sound Manager. diff --git a/examples/wip/checkerWaveFilter.js b/examples/wip/checkerWaveFilter.js new file mode 100644 index 000000000..e465f65f8 --- /dev/null +++ b/examples/wip/checkerWaveFilter.js @@ -0,0 +1,154 @@ +PIXI.CheckerWaveFilter = 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 = { + resolution: { type: 'f2', value: { x: width, y: height }}, + mouse: { type: 'f2', value: { x: 0, y: 0 }}, + time: { type: 'f', value: 1 } + }; + + // http://glsl.heroku.com/e#12260.0 + + // Heroku shader conversion + + this.fragmentSrc = [ + "precision mediump float;", + + "#ifdef GL_ES", + "precision highp float;", + "#endif", + + "uniform vec2 resolution;", + "uniform float time;", + + "//Scene Start", + + "//Floor", + "vec2 obj0(in vec3 p){", + "//obj deformation", + "p.y=p.y+sin(sqrt(p.x*p.x+p.z*p.z)-time*4.0)*0.5;", + "//plane", + "return vec2(p.y+3.0,0);", + "}", + "//Floor Color (checkerboard)", + "vec3 obj0_c(in vec3 p){", + "if (fract(p.x*.5)>.5)", + "if (fract(p.z*.5)>.5)", + "return vec3(0,1,1);", + "else", + "return vec3(1,1,1);", + "else", + "if (fract(p.z*.5)>.5)", + "return vec3(1,1,1);", + "else", + "return vec3(0,1,1);", + "}", + + "//Scene End", + + "void main(void){", + "vec2 vPos=-1.0+2.0*gl_FragCoord.xy/resolution.xy;", + + "//Camera animation", + "vec3 vuv=vec3(0,2,sin(time*0.1));//Change camere up vector here", + "vec3 prp=vec3(-sin(time*0.6)*8.0,0,cos(time*0.4)*8.0); //Change camera path position here", + "vec3 vrp=vec3(0,-5,0); //Change camere view here", + + + "//Camera setup", + "vec3 vpn=normalize(vrp-prp);", + "vec3 u=normalize(cross(vuv,vpn));", + "vec3 v=cross(vpn,u);", + "vec3 vcv=(prp+vpn);", + "vec3 scrCoord=vcv+vPos.x*u*resolution.x/resolution.y+vPos.y*v;", + "vec3 scp=normalize(scrCoord-prp);", + + "//Raymarching", + "const vec3 e=vec3(0.1,0,0);", + "const float maxd=80.0; //Max depth", + + "vec2 s=vec2(0.1,0.0);", + "vec3 c,p,n;", + + "float f=1.0;", + "for(int i=0;i<156;i++){", + "if (abs(s.x)<.01||f>maxd) break;", + "f+=s.x;", + "p=prp+scp*f;", + "s=obj0(p);", + "}", + + "if (f0.){", + "//It does, compute the distance camera-sphere", + "float s=-b-sqrt(q);", + + "if(s.01)", + "{", + "// So far this is the minimum distance, save it. And also", + "// compute the bouncing ray vector into 'n'", + "t=s,", + "n=normalize(p2+d*t),", + "m=2;", + "}", + "}", + "}", + "return m;", + "}", + + "const float PI_2_DIV_3 = 1.0471975512;", + + "vec3 S(in vec3 o,in vec3 d, vec2 uv)", + "{", + "float t;", + "vec3 n;", + + "vec3 cumulated_color = vec3(0.);", + + "//Search for an intersection ray Vs World.", + "int m=T(o,d,t,n);", + "float attenuationFactor = 1.0;", + + "float f = 0.;", + "for(int i = 0; i<3; i++) //Max recursivity - 3 bounces", + "{", + "if(0==m) // m==0", + "{", + "return ( cumulated_color + attenuationFactor * vec3(.7,.6,1)*pow(1.-d.z,4.));", + "}", + + "vec3 h = o+d*t; // h = intersection coordinate", + "vec3 l = normalize(vec3(9.,9.,16.)+h*-1.); // 'l' = direction to light (with random delta for soft-shadows).", + "vec3 r = d+n*(dot(n,d)*-2.); // r = The half-vector", + + "//Calculated the lambertian factor", + "float b=dot(l,n);", + + "//Calculate illumination factor (lambertian coefficient > 0 or in shadow)?", + "if(b<0.||T(h,l,t,n) !=0)", + "b=0.;", + + "// Calculate the color 'p' with diffuse and specular component", + "float p= 0.;", + "if (b!=0.)", + "{", + "p = pow(dot(l,r),99.);", + "}", + + "if(m==1){", + + "h=h*.2; //No sphere was hit and the ray was going downward: Generate a floor color", + "float cond = (float(ceil(h.x + iGlobalTime)+ceil(h.y+iGlobalTime)));", + "//if odd", + "if (fract(cond/2.) == 0.)", + "return (cumulated_color+attenuationFactor *vec3(3.,1.,1.)*(b*0.2+0.1));", + "else", + "return (cumulated_color+attenuationFactor*vec3(3.,3.,3.)*(b*0.2+0.1));", + "}", + "cumulated_color += attenuationFactor*vec3(p);", + "attenuationFactor *= 0.5;", + "o = h;", + "d = r;", + "m=T(h,r,t,n);", + "f++;", + "}", + "return vec3(0.0);", + "}", + + "const float inv_256 = 0.00390625;", + + + "void main(void)", + "{", + "vec2 uv = gl_FragCoord.xy / iResolution.xy; //some optimization here to do", + "vec3 g=normalize(vec3(-6.,-16.,0.)); // Camera direction", + "vec3 a=normalize(cross(g,vec3(0.,0.,1.)))*.002; // Camera up vector...Seem Z is pointing up :/ WTF !", + "vec3 b=normalize(cross(a,g))*.002; // The right vector, obtained via traditional cross-product", + "vec3 c=(a+b)*-256.+g;", + "vec3 p= vec3(13,13,13); // Default pixel color is almost pitch black", + "highp vec3 t=a*0.5*99.+b*0.5*99.;", + "p=64.*S(vec3(17.,16.,8.)+t,normalize(t*-1.+(a*(gl_FragCoord.x)+b*(gl_FragCoord.y)+c)*16.), uv)*3.5+p; // +p for color accumulation", + "gl_FragColor = vec4(p * inv_256,1.0);", + + "}"]; + + +} + +PIXI.RayTracedBallsFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.RayTracedBallsFilter.prototype.constructor = PIXI.RayTracedBallsFilter; + +Object.defineProperty(PIXI.RayTracedBallsFilter.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/tex07.jpg'); + +} + +var filter; +var sprite; + +function create() { + + sprite = game.add.sprite(0, 0, 'texture'); + sprite.width = 800; + sprite.height = 600; + + filter = new PIXI.RayTracedBallsFilter(sprite.width, sprite.height, sprite.texture); + + sprite.filters = [filter]; + +} + +function update() { + + filter.iGlobalTime = game.time.totalElapsedSeconds(); + filter.uniforms.iMouse.value.x = game.input.x; + filter.uniforms.iMouse.value.y = game.input.y; + +} + +function render() { +} diff --git a/examples/wip/rotationalFractalsFilter.js b/examples/wip/rotationalFractalsFilter.js new file mode 100644 index 000000000..5781f205a --- /dev/null +++ b/examples/wip/rotationalFractalsFilter.js @@ -0,0 +1,104 @@ +PIXI.RotationalFractalsFilter = 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 }}, + iMouse: { type: 'f3', value: { x: 0, y: 0, z: 0 }}, + iGlobalTime: { type: 'f', value: 1 }, + iDate: { type: 'f4', value: dates }, + iChannel0: { type: 'sampler2D', value: texture, wrap: 'repeat' } + }; + + // Shader by gleurop (https://www.shadertoy.com/view/MsXGRS) + 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", + + "vec3 hsv(in float h, in float s, in float v) {", + "return mix(vec3(1.0), clamp((abs(fract(h + vec3(3, 2, 1) / 3.0) * 6.0 - 3.0) - 1.0), 0.0 , 1.0), s) * v;", + "}", + + "void main() {", + "vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / iResolution.xy;", + "p.x *= iResolution.x / iResolution.y;", + "vec2 c = vec2(-iGlobalTime*0.154, iGlobalTime*0.2485);", + "float d = 1.0;", + "vec3 col = vec3(0);", + "float t = iGlobalTime;", + "for (int i = 0; i < 20; i++) {", + "float r = length(p);", + "p /= r;", + "p = asin(sin(p/r + c));", + "col += hsv(r, max(1.0-dot(p,p), 0.0), 1.0);", + "}", + "gl_FragColor = vec4(sin(col)*0.5+0.5,", + "1.0);", + "}"]; + + +} + +PIXI.RotationalFractalsFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.RotationalFractalsFilter.prototype.constructor = PIXI.RotationalFractalsFilter; + +Object.defineProperty(PIXI.RotationalFractalsFilter.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/tex07.jpg'); + +} + +var filter; +var sprite; + +function create() { + + sprite = game.add.sprite(0, 0, 'texture'); + sprite.width = 800; + sprite.height = 600; + + filter = new PIXI.RotationalFractalsFilter(sprite.width, sprite.height, sprite.texture); + + sprite.filters = [filter]; + +} + +function update() { + + filter.iGlobalTime = game.time.totalElapsedSeconds(); + filter.uniforms.iMouse.value.x = game.input.x; + filter.uniforms.iMouse.value.y = game.input.y; + +} + +function render() { +} diff --git a/examples/wip/rotoZoomerFilter.js b/examples/wip/rotoZoomerFilter.js new file mode 100644 index 000000000..e7ff2e76e --- /dev/null +++ b/examples/wip/rotoZoomerFilter.js @@ -0,0 +1,117 @@ +PIXI.RotoZoomerFilter = 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 }}, + iMouse: { type: 'f3', value: { x: 0, y: 0, z: 0 }}, + iGlobalTime: { type: 'f', value: 1 }, + iDate: { type: 'f4', value: dates }, + iChannel0: { type: 'sampler2D', value: texture, wrap: 'nearest-repeat' } + }; + + // Shader by triggerHLM (https://www.shadertoy.com/view/lsfGDH) + 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", + + "float time=iGlobalTime*0.2;", + + + "float pi = 3.14159265;", + + + "void main( void )", + "{", + + "vec2 position = vec2(640.0/2.0+640.0/2.0*sin(time*2.0), 360.0/2.0+360.0/2.0*cos(time*3.0));", + "vec2 position2 = vec2(640.0/2.0+640.0/2.0*sin((time+2000.0)*2.0), 360.0/2.0+360.0/2.0*cos((time+2000.0)*3.0));", + + + "vec2 offset = vec2(640.0/2.0, 360.0/2.0) ;", + "vec2 offset2 = vec2(6.0*sin(time*1.1), 3.0*cos(time*1.1));", + + "vec2 oldPos = (gl_FragCoord.xy-offset);", + + "float angle = time*2.0;", + + "vec2 newPos = vec2(oldPos.x *cos(angle) - oldPos.y *sin(angle),", + "oldPos.y *cos(angle) + oldPos.x *sin(angle));", + + + "newPos = (newPos)*(0.0044+0.004*sin(time*3.0))-offset2;", + "vec2 temp = newPos;", + "newPos.x = temp.x + 0.4*sin(temp.y*2.0+time*8.0);", + "newPos.y = (-temp.y + 0.4*sin(temp.x*2.0+time*8.0));", + "vec4 final = texture2D(iChannel0,newPos);", + "//final = texture2D(texCol,gl_FragCoord.xy*vec2(1.0/640, -1.0/360));", + "gl_FragColor = vec4(final.xyz, 1.0);", + + "}"]; + + +} + +PIXI.RotoZoomerFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.RotoZoomerFilter.prototype.constructor = PIXI.RotoZoomerFilter; + +Object.defineProperty(PIXI.RotoZoomerFilter.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.RotoZoomerFilter(sprite.width, sprite.height, sprite.texture); + + sprite.filters = [filter]; + +} + +function update() { + + filter.iGlobalTime = game.time.totalElapsedSeconds(); + filter.uniforms.iMouse.value.x = game.input.x; + filter.uniforms.iMouse.value.y = game.input.y; + +} + +function render() { +} diff --git a/examples/wip/shinyTaffyFilter.js b/examples/wip/shinyTaffyFilter.js new file mode 100644 index 000000000..35b151808 --- /dev/null +++ b/examples/wip/shinyTaffyFilter.js @@ -0,0 +1,125 @@ +PIXI.ShinyTaffyFilter = 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 }}, + iMouse: { type: 'f3', value: { x: 0, y: 0, z: 0 }}, + iGlobalTime: { type: 'f', value: 1 }, + iDate: { type: 'f4', value: dates }, + iChannel0: { type: 'sampler2D', value: texture, wrap: 'repeat' } + }; + + // Shader by huttarl (https://www.shadertoy.com/view/4dXGWr) + 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", + + "/* What I'd like to do next is treat the color values from the texture", + "as surface normals, and do diffuse shading accordingly.", + "Maybe also keep the colors as colors.", + "To do:", + "- apply simple averaging or gaussian filter to smooth out the normals", + "- apply specular reflection */", + + "vec3 s = normalize(vec3(5.0, -1.0, 5.0)); // light direction", + "float texelSize = 1.0 / 1024.0;", + + "vec3 blur(vec2 uv) {", + "vec2 x = vec2(texelSize, 0.0);", + "vec2 y = vec2(0.0, texelSize);", + "return (texture2D(iChannel0, uv).xyz * 2.0 +", + "texture2D(iChannel0, uv + x).xyz +", + "texture2D(iChannel0, uv - x).xyz +", + "texture2D(iChannel0, uv + y).xyz +", + "texture2D(iChannel0, uv - y).xyz) * (1.0 / 6.0);", + "}", + + "void main(void)", + "{", + "vec2 uv = gl_FragCoord.xy / iResolution.xx;", + "vec2 uv2 = uv + vec2(sin(iGlobalTime + uv.y * 10.0) * 0.2,", + "cos(iGlobalTime + uv.x * 10.0) * 0.2);", + + "vec3 col = texture2D(iChannel0, uv2).xyz;", + "vec3 n = normalize(blur(uv2) - 0.5);", + + "float dot1 = dot(s, n);", + "vec3 r = -s + 2.0 * dot1 * n;", + "float diffuse = max(dot1, 0.0);", + + "vec3 v = normalize(vec3(-uv.x, -uv.y, 2.0)); // viewer angle", + "float spec = pow(dot(r, v), 16.0);", + + "gl_FragColor = vec4(vec3(0.1 +", + "col * 0.4 +", + "diffuse * 0.4 +", + "spec * 3.0), 1.0);", + "}"]; + + +} + +PIXI.ShinyTaffyFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.ShinyTaffyFilter.prototype.constructor = PIXI.ShinyTaffyFilter; + +Object.defineProperty(PIXI.ShinyTaffyFilter.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/tex01.jpg'); + +} + +var filter; +var sprite; + +function create() { + + sprite = game.add.sprite(0, 0, 'texture'); + sprite.width = 800; + sprite.height = 600; + + filter = new PIXI.ShinyTaffyFilter(sprite.width, sprite.height, sprite.texture); + + sprite.filters = [filter]; + +} + +function update() { + + filter.iGlobalTime = game.time.totalElapsedSeconds(); + filter.uniforms.iMouse.value.x = game.input.x; + filter.uniforms.iMouse.value.y = game.input.y; + +} + +function render() { +} diff --git a/examples/wip/sineWaveFixedBaseFilter.js b/examples/wip/sineWaveFixedBaseFilter.js new file mode 100644 index 000000000..b42370d1c --- /dev/null +++ b/examples/wip/sineWaveFixedBaseFilter.js @@ -0,0 +1,106 @@ +PIXI.SineWaveFixedBaseFilter = 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 }}, + iMouse: { type: 'f3', value: { x: 0, y: 0, z: 0 }}, + iGlobalTime: { type: 'f', value: 1 }, + iDate: { type: 'f4', value: dates }, + iChannel0: { type: 'sampler2D', value: texture, wrap: 'repeat' } + }; + + // Shader by BrokenBit (https://www.shadertoy.com/view/MsXGzX) + 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)", + "{", + "vec2 uv = gl_FragCoord.xy / iResolution.xy;", + + "// Flip-a-roo.", + "uv.y *= -1.0;", + + "// Represents the v/y coord(0 to 1) that will not sway.", + "float fixedBasePosY = 0.0;", + + "// Configs for you to get the sway just right.", + "float speed = 3.0;", + "float verticleDensity = 6.0;", + "float swayIntensity = 0.2;", + + "// Putting it all together.", + "float offsetX = sin(uv.y * verticleDensity + iGlobalTime * speed) * swayIntensity;", + + "// Offsettin the u/x coord.", + "uv.x += offsetX * (uv.y - fixedBasePosY);", + + "gl_FragColor = texture2D(iChannel0, uv);", + "}"]; + +} + +PIXI.SineWaveFixedBaseFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.SineWaveFixedBaseFilter.prototype.constructor = PIXI.SineWaveFixedBaseFilter; + +Object.defineProperty(PIXI.SineWaveFixedBaseFilter.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.SineWaveFixedBaseFilter(sprite.width, sprite.height, sprite.texture); + + sprite.filters = [filter]; + +} + +function update() { + + filter.iGlobalTime = game.time.totalElapsedSeconds(); + filter.uniforms.iMouse.value.x = game.input.x; + filter.uniforms.iMouse.value.y = game.input.y; + +} + +function render() { +} diff --git a/examples/wip/spaceRacingLiteFilter.js b/examples/wip/spaceRacingLiteFilter.js new file mode 100644 index 000000000..820aca668 --- /dev/null +++ b/examples/wip/spaceRacingLiteFilter.js @@ -0,0 +1,713 @@ +PIXI.SpaceRacingLiteFilter = 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 }}, + iMouse: { type: 'f3', value: { x: 0, y: 0, z: 0 }}, + iGlobalTime: { type: 'f', value: 1 }, + iDate: { type: 'f4', value: dates }, + iChannel1: { type: 'sampler2D', value: texture, wrap: 'repeat' } + }; + + // Shader by Kali (https://www.shadertoy.com/view/XsBGzw) + 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 iChannel1;", + "// add any extra uniforms here", + + "// Space Racing Lite", + + "// Distance function and initial design for space car is by eiffie:", + "// https://www.shadertoy.com/view/ldjGRh", + "// the rest is by me but he also helped to optimize the code.", + + "// I removed some features by default because the original was crashing the Shadertoy browser", + "// for win7 users - try commenting this lines to see if the full version compiles for you:", + + "#define LOW_QUALITY // No reflections, no shadows, no planet, reduced ray steps & detail", + "#define NO_HUD", + + "//#define LOOP_BREAKS // Could speed up, speed down, or just make your browser crash!", + + + + "#ifdef LOW_QUALITY", + "#define RAY_STEPS 65", + "#define SHADOW_STEPS 0", + "#define ITERATIONS 5", + "#define MAX_DIST 30.", + "#else", + "#define RAY_STEPS 75", + "#define SHADOW_STEPS 40", + "#define ITERATIONS 6", + "#define MAX_DIST 35.", + "#endif", + "#define LIGHT_COLOR vec3(1.,.85,.6)", + "#define AMBIENT_COLOR vec3(.7,.85,1.)", + "#define SUN_COLOR vec3(1.,.8,.5)", + "#define TUBE_COLOR vec3(1.,.6,.25)*1.2", + "#define CAR_COLOR vec3(.4,.7,1.)", + "#define TURBINES_COLOR vec3(.6,.75,1.)", + "#define HUD_COLOR vec3(0.6,1.,0.3)", + "#define PLANET_COLOR vec3(101., 153., 189.)/256.", + + "#define CAR_SCALE 4.", + "#define SPECULAR 0.4", + "#define DIFFUSE 2.0", + "#define AMBIENT 0.4", + + "#define BRIGHTNESS .9", + "#define GAMMA 1.1", + "#define SATURATION .85", + + + "#define DETAIL .004", + "#define SPEED 8.", + "#define t (mod(iGlobalTime,500.)+10.)*SPEED", + + "#define LIGHTDIR normalize(vec3(0.6,-0.2,-1.))", + + "// ------------------------------------------------------------------", + "// Global Variables", + "// ------------------------------------------------------------------", + + "float FOLD=2.; // controls fractal fold and track width", + "const vec3 planetpos=vec3(-3.5,1.,-5.); // planet position", + "const vec2 tubepos=vec2(0.35,0.); // light tubes pos relative to FOLD", + "mat2 trmx;//the turbine spinner", + "float det=0.; // detail level (varies with distance)", + "float backcam; // back cam flag", + "vec3 carpos; // car position", + "vec3 carvec; // car pointing vector", + "mat3 carrot; // car rotation", + "float hitcar; // ray-car hit flag", + "mat2 fractrot; // rot mat for fractal (set in main)", + "mat2 cartilt; // secondary car rotation", + "float minT, minL; // min distance traps for glows of tube and turbines", + "float ref; // reflection flag", + "float tubeinterval; // tube tiling (for glow and lighting)", + + + "// ------------------------------------------------------------------", + "// General functions", + "// ------------------------------------------------------------------", + + "mat2 rot(float a) {", + "return mat2(cos(a),sin(a),-sin(a),cos(a));", + "}", + + "mat3 lookat(vec3 fw,vec3 up){", + "fw=normalize(fw);vec3 rt=normalize(cross(fw,normalize(up)));return mat3(rt,cross(rt,fw),fw);", + "}", + + "float smin(float a,float b,float k){return -log(exp(-k*a)+exp(-k*b))/k;}//from iq", + + "float Sphere(vec3 p, vec3 rd, float r){", + "float b = dot( -p, rd );", + "float inner = b * b - dot( p, p ) + r * r;", + "if( inner < 0.0 ) return -1.0;", + "return b - sqrt( abs(inner) );", + "}", + + + "// ------------------------------------------------------------------", + "// Track", + "// ------------------------------------------------------------------", + + "// the track function, just some curves", + "vec3 path(float ti) {", + "float freq=.5, amp=1.; // for trying different settings", + "ti*=freq;", + "float x=cos(cos(ti*.35682)+ti*.2823)*cos(ti*.1322)*1.5;", + "float y=sin(ti*.166453)*4.+cos(cos(ti*.125465)+ti*.17354)*cos(ti*.05123)*2.;", + "vec3 p=vec3(x,y,ti/freq);", + "return p;", + "}", + + "// see if we are in the tunnel, and used also by distance function", + "float tunnel(float z) {", + "return abs(100.-mod(z+15.,200.))-30.;", + "}", + + + "// ------------------------------------------------------------------", + "// DE functions", + "// ------------------------------------------------------------------", + + + "// carcarspacecar by eiffie // (with some mods by Kali)", + "// a reconfig of the carcar's tires (someday I will have to do an animation from the original to this)", + "//the DE looks a bit long but there are actually fewer instructions than the car", + + "float carcarDE(in vec3 p0){", + "p0.xy*=cartilt;", + "p0*=CAR_SCALE;", + "vec3 p=p0;", + "p.y+=1.24;", + "float r=length(p.yz);", + "float d=length(max(vec3(abs(p.x)-0.35,r-1.92,-p.y+1.4),0.0))-0.05;", + "d=max(d,p.z-1.05);", + "p=p0+vec3(0.0,-0.22,0.39);", + "p.xz=abs(p.xz);", + "p.xyz-=vec3(0.72,0.0,1.06);", + "float w1=0.23,w2=0.24;", + "if(p0.z<0.0){//this is discontinuous yet works unless you stand in front of the rear turbines", + "w1=0.23,w2=0.05; //where you would get sucked into the blades anyways", + "p=p.xzy; //so i'm comfortable with it :)", + "}", + "r=length(p.xy);", + "d=smin(d,length(vec2(max(abs(p.z)-w2,0.0),r-w1))-0.02,8.0);//done with the car shape, the rest is just turbines and could be replaced with lights or something", + "d=min(d,(length(p*vec3(1.,1.,.6))-.08-p0.z*.03));", + "p.xy=trmx*p.xy;//spin", + "float d2=min(abs(p.x),abs(p.y))*.15;//4 blades", + "//p.xy=mat2(0.707,-0.707,0.707,0.707)*p.xy;//45 degree turn", + "//d2=min(d2,min(abs(p.x),abs(p.y))*.2);//8 blades", + "d2=max(r-w1-.05,max(d2-0.005,abs(p.z)-w2+0.04));", + "d2=min(d2,(length(p)-.05-p0.z*.035)*.07);", + "d2=min(d2,max(d+.02,max(abs(p0.y-.07),abs(p0.x)-.4+min(0.,p0.z)))*.18);", + "minL=min(minL,d2);//catch the minimum distance to the glowing parts", + "// I used d2 only for glows (Kali)", + "return d/CAR_SCALE;// *carScale", + "}", + + + "vec3 carcarCE(in vec3 p0){//coloring", + "p0*=CAR_SCALE;", + "vec4 trpc=vec4(0.);//color trap (taking samples when finding the norm)// not for now (Kali)", + + "//right here you should inv-transform p0 as it gets used later", + "//p0=(p0-carPos)*carRot/carScale;//or something like that??", + "p0.xy*=cartilt;", + "vec3 p=p0;", + "p.y+=1.24;", + "float r=length(p.yz);", + "float d=length(max(vec3(abs(p.x)-0.35,r-1.92,-p.y+1.4),0.0))-0.05;", + "d=max(d,p.z-1.0);", + "p=p0+vec3(0.0,-0.22,0.39);", + "p.xz=abs(p.xz);", + "p.xyz-=vec3(0.72,0.0,1.06);", + "float w1=0.2,w2=0.24;", + "if(p0.z<0.0){//this is discontinuous yet works unless you stand in front of the rear turbines", + "w1=0.23,w2=0.05; //where you would get sucked into the blades anyways", + "p=p.xzy; //so i'm comfortable with it :)", + "}", + "r=length(p.xy);", + "d=smin(d,length(vec2(max(abs(p.z)-w2,0.0),r-w1))-0.02,8.0);//done with the car shape, the rest is just turbines and could be replaced with lights or something", + "p.xy=trmx*p.xy;", + "float d2=min(abs(p.x),abs(p.y));//4 blades", + "p.xy=mat2(0.707,-0.707,0.707,0.707)*p.xy;//45 degrees", + "d2=min(d2,min(abs(p.x),abs(p.y)));//8 blades", + "d2=max(r-w1+0.02,max(d2-0.005,abs(p.z)-w2+0.04));", + "//up to here it is the same as DE, now accumulate colors", + "if(d20.05-p0.z*0.09 || p0.z>0.25) &&", + "length(max(abs(p0.xz+vec2(-p0.z*.03,-0.5))-vec2(0.15+p0.z*.03,0.4),0.0))>0.1)", + "trpc+=vec4(CAR_COLOR,16.0);", + "else trpc+=vec4(CAR_COLOR*.4,2.0);//the windsheild", + "}", + "return trpc.xyz; // *carScale", + "}", + + "//-------------------------------------------", + + "// DE for tubes", + "float tubes(vec3 pos) {", + "pos.x=abs(pos.x)-tubepos.x-FOLD;", + "pos.y+=tubepos.y;", + "return (length(pos.xy)-.05);", + "}", + + "// ------------------------------------------------------------------", + "// SCENE DE", + "// ------------------------------------------------------------------", + + "float de(vec3 pos) {", + "vec3 carp=pos-carpos; // scale car coordinates", + "carp=carrot*carp; // rotate car", + "pos.xy-=path(pos.z).xy; // transform coordinates to follow track", + "FOLD=1.7+pow(abs(100.-mod(pos.z,200.))/100.,2.)*2.; //varies fractal fold & track width", + "pos.x-=FOLD;", + "float hid=0.;", + "vec3 tpos=pos;", + "tpos.z=abs(2.-mod(tpos.z,4.));", + "vec4 p=vec4(tpos,1.);", + "for (int i=0; iDETAIL) {", + "vec3 p = pos - totdist * sdir;", + "dist = de(p);", + "sh = min(sh, 10.*max(0.0,dist)/totdist);", + "sh*= sign(max(0.,dist-DETAIL));", + "totdist += max(0.02,dist);", + "}", + "#ifdef LOOP_BREAKS", + "else break;", + "#endif", + "}", + + "return clamp(sh,0.,1.0);", + "}", + + "#endif", + + "float calcAO(vec3 pos, vec3 nor) {", + "float hr,dd,aoi=0.,sca=1.,totao=0.;", + "hr = .075*aoi*aoi;dd = de(nor * hr + pos);totao += (hr-dd)*sca;sca*=.6;aoi++;", + "hr = .075*aoi*aoi;dd = de(nor * hr + pos);totao += (hr-dd)*sca;sca*=.55;aoi++;", + "hr = .075*aoi*aoi;dd = de(nor * hr + pos);totao += (hr-dd)*sca;sca*=.55;aoi++;", + "hr = .075*aoi*aoi;dd = de(nor * hr + pos);totao += (hr-dd)*sca;sca*=.55;aoi++;", + "return clamp( 1.0 - 4.*totao, 0., 1.0 );", + "}", + + + "// ------------------------------------------------------------------", + "// Light and Coloring", + "// ------------------------------------------------------------------", + + + + "vec3 shade(in vec3 p, in vec3 dir, in vec3 n) {", + + "float savehitcar=hitcar;", + + "vec3 trackoffset=-vec3(path(p.z).xy,0.);", + "vec3 pos=p;", + "vec3 col=vec3(.5); // main color", + "vec3 carp=pos-carpos; //scaled coordinates for the car", + "carp=carrot*carp; // rotate car", + "pos+=trackoffset; // apply track transformation to the coordinates", + "// track lines", + "if (pos.y<.5) col+=pow(max(0.,.2-abs(pos.x))/.2*abs(sin(pos.z*2.)),8.)*TUBE_COLOR*2.;", + "pos.x=abs(pos.x);", + "// fake AO for the tunnel's upper corners", + "if(tunnel(pos.z)<0.)", + "col*=1.-pow(max(0.5,1.-length(pos.xy+vec2(-FOLD*1.5,-.85))),5.)*max(0.,1.+pos.y);", + "if (tubes(pos)0.) {", + "falloff1=pow(max(0.,1.-.15*distance(vec3(p.xy,0.),vec3(-tpos1.xy,0.))),4.);", + "falloff2=pow(max(0.,1.-.15*distance(vec3(p.xy,0.),vec3(-tpos2.xy,0.))),4.);", + "} else {", + "falloff1=pow(max(0.,1.-.2*distance(vec3(p.xy,0.),vec3(-tpos1.xy,0.))),4.);", + "falloff2=pow(max(0.,1.-.2*distance(vec3(p.xy,0.),vec3(-tpos2.xy,0.))),4.);", + "}", + + "float diff, spec;", + + "vec3 r=reflect(LIGHTDIR,n);", + + "// tube1 calcs", + "diff=max(0.,dot(tube1lightdir,-n));", + "diff+=max(0.,dot(normalize(tube1lightdir+vec3(0.,0.,.2)),-n))*.5; // add 2 more", + "diff+=max(0.,dot(normalize(tube1lightdir-vec3(0.,0.,.2)),-n))*.5; // with Z shifted", + "spec=pow(max(0.,dot(tube1lightdir+vec3(0.,0.,.4),r)),15.)*.7;", + "spec+=pow(max(0.,dot(tube1lightdir-vec3(0.,0.,.4),r)),15.)*.7;", + "float tl1=(falloff1*ao+diff+spec)*falloff1;", + + "// tube2 calcs", + "diff=max(0.,dot(tube2lightdir,-n));", + "diff+=max(0.,dot(normalize(tube2lightdir+vec3(0.,0.,.2)),-n))*.5;", + "diff+=max(0.,dot(normalize(tube2lightdir-vec3(0.,0.,.2)),-n))*.5;", + "spec=pow(max(0.,dot(tube2lightdir+vec3(0.,0.,.4),r)),15.)*.7;", + "spec+=pow(max(0.,dot(tube2lightdir-vec3(0.,0.,.4),r)),15.)*.7;", + "float tl2=(falloff2*ao+diff+spec)*falloff2;", + + "// sum tube lights - add ambient - apply tube intervall", + "vec3 tl=((tl1+tl2)*(.5+tubeinterval*.5))*TUBE_COLOR;//*(1.+tun*.5);", + + + "// --- Car lights ---", + + "// get the car turbines direction (aproximate)", + "vec3 carlightdir1=normalize(p-carpos+vec3(.2,0.06,.15));", + "vec3 carlightdir2=normalize(p-carpos+vec3(-.2,0.06,.15));", + "vec3 carlightdir3=normalize(p-carpos+vec3(.2,0.06,-.35));", + "vec3 carlightdir4=normalize(p-carpos+vec3(-.2,0.06,-.35));", + + "float cfalloff=pow(max(0.,1.-.1*distance(p,carpos)),13.); // car light falloff", + + "// accumulate diffuse", + "diff=max(0.,dot(carlightdir1,-n))*.5;", + "diff+=max(0.,dot(carlightdir2,-n))*.5;", + "diff+=max(0.,dot(carlightdir3,-n))*.5;", + "diff+=max(0.,dot(carlightdir4,-n))*.5;", + + "if (savehitcar<1.) diff*=clamp(1.-carlightdir1.y,0.,1.);", + + "// add ambient and save car lighting", + "vec3 cl=TURBINES_COLOR*((diff+spec*.0)*cfalloff+cfalloff*.3)*1.2;", + + "// --- Main light ---", + + "#ifdef LOW_QUALITY", + "float sh=ao;", + "#else", + "float sh=shadow(p, LIGHTDIR); // get shadow", + "#endif", + + "diff=max(0.,dot(LIGHTDIR,-n))*sh*1.3; // diffuse", + "float amb=(.4+.6*camlight)*.6; // ambient+camlight", + "spec=pow(max(0.,dot(dir,-r))*sh,20.)*SPECULAR; //specular", + "if (savehitcar>0.) {diff*=.8;amb*=.3;}", + "vec3 l=(amb*ao*AMBIENT_COLOR+diff*LIGHT_COLOR)+spec*LIGHT_COLOR;", + + "if (col==TUBE_COLOR) l=.3+vec3(camlight)*.7; // special lighting for tubes", + + "return col*(l+cl+tl); // apply all lights to the color", + "}", + + "// the planet shading...", + "// very simple and fast made, but for low res windowed mode it does the job :)", + "vec3 shadeplanet(vec3 pos, vec3 k) {", + + "vec3 n=normalize(planetpos+pos+.2); // tweaked sphere normal", + "float c=max(0.,dot(LIGHTDIR,normalize(k-n))); // surface value", + "vec3 col=PLANET_COLOR+vec3(c,c*c,c*c*c)*.7; // surface coloring", + "// add some noise", + "float noi=max(0.,texture2D(iChannel1,n.yz*.5).x-.6);", + "noi+=max(0.,texture2D(iChannel1,n.yz).x-.6);", + "noi+=max(0.,texture2D(iChannel1,n.yz*2.).x-.6);", + "col+=noi*(1.5-c)*.7;", + "return col*max(0.,dot(LIGHTDIR,-n)); // diff light", + "}", + + "// ------------------------------------------------------------------", + "// Raymarching + FX rendering", + "// ------------------------------------------------------------------", + + + "vec3 raymarch(in vec3 from, in vec3 dir)", + + "{", + "hitcar=0.;", + "ref=0.;", + "float totdist=0.;", + "float glow=0.;", + "float d=1000.;", + "vec3 p=from, col=vec3(0.5);", + + "float deta=DETAIL*(1.+backcam); // lower detail for HUD cam", + "vec3 carp=vec3(0.); // coordinates for car hit", + "vec3 carn=vec3(0.); // normal for car", + "float cardist=0.; // ray length for car", + "vec3 odir=dir; // save original ray direction", + + "for (int i=0; idet && totdist0. && ref<1.) { // hit car, bounce ray (only once)", + "p=p-abs(d-det)*dir; // backstep", + "carn=normal(p); // save car normal", + "carp=p; // save car hit pos", + "dir=reflect(dir,carn); // reflect ray", + "p+=det*dir*10.; // advance ray", + "d=10.; cardist=totdist;", + "ref=1.;", + "}", + "#endif", + "}", + "#ifdef LOOP_BREAKS", + "else break;", + "#endif", + "}", + + "tubeinterval=abs(1.+cos(p.z*3.14159*.5))*.5; // set light tubes interval", + "float cglow=1./(1.0+minL*minL*5000.0); // car glow", + "float tglow=1./(1.0+minT*minT*5000.0); // tubes glow", + "float l=max(0.,dot(normalize(-dir),normalize(LIGHTDIR))); // lightdir gradient", + "vec3 backg=AMBIENT_COLOR*.4*max(0.1,pow(l,5.)); // background", + "float lglow=pow(l,50.)*.5+pow(l,200.)*.5; // sun glow", + + "if (d<.5) { // hit surface", + "vec3 norm=normal(p); // get normal", + "p=p-abs(d-det)*dir; // backstep", + "col=shade(p, dir, norm); // get shading", + "col+=tglow*TUBE_COLOR*pow(tubeinterval,1.5)*2.; // add tube glow", + "col = mix(backg, col, exp(-.015*pow(abs(totdist),1.5))); // distance fading", + + "} else { // hit background", + "col=backg; // set color to background", + "col+=lglow*SUN_COLOR; // add sun glow", + "col+=glow*pow(l,5.)*.035*LIGHT_COLOR; // borders glow", + + "#ifdef LOW_QUALITY", + "vec3 st = (dir * 3.+ vec3(1.3,2.5,1.25)) * .3;", + "for (int i = 0; i < 14; i++) st = abs(st) / dot(st,st) - .9;", + + "col+= min( 1., pow( min( 5., length(st) ), 3. ) * .0025 ); // add stars", + "#else", + "float planet=Sphere(planetpos,dir, 2.); // raytrace planet", + + "// kaliset formula - used for stars and planet surface", + "float c;", + "if (planet>0.) c=1.; else c=.9; // different params for planet and stars", + "vec3 st = (dir * 3.+ vec3(1.3,2.5,1.25)) * .3;", + "for (int i = 0; i < 14; i++) st = abs(st) / dot(st,st) - c;", + + "col+= min( 1., pow( min( 5., length(st) ), 3. ) * .0025 ); // add stars", + + "// planet atmosphere", + "col+=PLANET_COLOR*pow(max(0.,dot(dir,normalize(-planetpos))),100.)*150.*(1.-dir.x);", + "// planet shading", + "if (planet>0.) col=shadeplanet(planet*dir,st);", + "#endif", + + "}", + "// car shading", + + "// add turbine glows", + + "#ifdef LOW_QUALITY", + "cglow*=1.15;", + "#else", + "if (ref>0.) {", + "ref=0.;", + "col=shade(carp,odir,carn)+col*.3; // car shade + reflection", + "// I wanted a lighter background for backward reflection", + "l=max(0.,dot(normalize(-odir),normalize(LIGHTDIR)));", + "backg=AMBIENT_COLOR*.4*max(0.1,pow(l,5.));", + "col = mix(backg, col,exp(-.015*pow(abs(cardist),1.5))); // distance fading", + "}", + "#endif", + + + "col+=TURBINES_COLOR*pow(abs(cglow),2.)*.4;", + "col+=TURBINES_COLOR*cglow*.15;", + + + "return col;", + "}", + + "// simple HUD track graph with transparency", + "vec4 showtrack(vec2 p) {", + "p.x+=.25;", + "vec2 uv=p;", + "float uvpos=uv.x+1.5;", + "vec3 pth=path((uvpos-1.5)*30.+t)*.05;", + "float curpos=path(t).x*.05;", + "float curs=pow(max(0.,1.-length(uv+vec2(0.,curpos))*2.),10.)*max(0.5,sin(iGlobalTime*10.))*2.;", + "uv.xy=uv.xy-(vec2(uvpos,0.))*rot(pth.x/uvpos);", + "float dotline=pow(max(0.,1.-abs(uv.y)*5.),30.);", + "float graph=(curs+dotline);", + "return vec4((graph+.4)*HUD_COLOR,1.-.5*pow(abs(.025-mod(p.y*2.,.05))/.025,2.));", + "}", + + + "// ------------------------------------------------------------------", + "// Main code - Camera - HUD", + "// ------------------------------------------------------------------", + + + "void main(void)", + "{", + "minL=minT=1000.; // initialize min distance glows", + "fractrot=rot(.5); // mat2D for the fractal formula", + "vec3 carpos0=vec3(0.,-0.2,.0); // set relative car pos (unused now, only sets height)", + "carpos=vec3(carpos0+vec3(0.,0.,t)); // real car pos", + "vec3 carmove=path(carpos.z); carmove.x*=1.+FOLD*.1; // get pos, exagerate x pos based on track width.", + "carvec=normalize((path(carpos.z+2.)-carmove)*vec3(FOLD*.25,1.,1.)); // car fwd vector", + "carrot=lookat(-carvec,vec3(0.,1.,0.)); // car rotation", + "cartilt=rot(-carvec.x*2.); // xy rotation based on distance from center", + "carpos.xy+=carmove.xy-vec2(carvec.x,0.)*FOLD*.5; // move away from center when turning", + "float tim=iGlobalTime*12.0;", + "trmx=mat2(cos(tim),-sin(tim),sin(tim),cos(tim));//the turbine spinner", + + "// --- camera & mouse ---", + + "vec2 uv = gl_FragCoord.xy / iResolution.xy*2.-1.;", + "uv.y*=iResolution.y/iResolution.x;", + "vec2 mouse=(iMouse.xy/iResolution.xy-.5)*vec2(7.,1.5);", + "if (iMouse.z<1.) { // if no mouse, alternate rear and back cam", + "mouse=vec2(sin(iGlobalTime)*.7,2.+sin(iGlobalTime*.2)*.22)", + "*min(0.,sign(10.-mod(iGlobalTime,20.)));", + "}", + "vec3 dir=normalize(vec3(uv*.8,1.));", + + "vec3 campos=vec3(0.,0.2,-.6); // original relative camera position", + "//rotate camera with mouse", + "campos.yz=(campos.yz-carpos0.yz)*rot(mouse.y)+carpos0.yz;", + "campos.xz=(campos.xz-carpos0.xz)*rot(mouse.x)+carpos0.xz;", + "campos.x-=carvec.x*FOLD; // follow car x pos a bit when turning", + + "vec3 from;", + + "float fixcam=5.;", + "float mt=mod(t/SPEED,fixcam*2.);", + "//fixed cam every 15 seconds, random position, point at car position", + "if ((mod(iGlobalTime,20.)>15. && iMouse.z<1.)) {", + "fixcam*=SPEED;", + "from=path(floor(t/fixcam)*fixcam+fixcam*.5);", + "//from.x+=1.; from.y+=.5;", + "vec2 fixpos=(texture2D(iChannel1,vec2(from.z*.21325)).xy-.5)*vec2(FOLD*2.-.3,1.);", + "fixpos.x+=sign(fixpos.x)*.3; fixpos.y+=.2;", + "from.xy+=fixpos;", + "dir=lookat(normalize(carpos-from),vec3(0.,1.,0.))*normalize(dir+vec3(0.,0.,0.5));", + + "} else { //normal cam", + "from=path(t+campos.z)+campos;", + "dir.y-=.3*campos.z;", + "dir=lookat(normalize(carpos-from),vec3(0.,1.,0.))*normalize(dir);", + "}", + + "vec4 hud=vec4(0.);", + + "#ifndef NO_HUD", + "//HUD (hud camera was going to be transparent but won't compile)", + "backcam=0.;", + "vec2 huv=uv+vec2(.75,.44);", + "if (length(huv*huv*huv*vec2(5.,50.))<.05) hud=showtrack(huv*2.); // track HUD", + "uv+=vec2(-.75,.44);", + "if (length(uv*uv*uv*vec2(5.,50.))<.05) { //set ray data for HUD cam", + "backcam=1.;", + "uv*=6.;", + "dir=normalize(vec3(uv.xy*.6,-1.));", + "from=vec3(carvec.x*.5,0.1,0.)+path(t-campos.z*1.7);", + "dir=lookat(-normalize(carpos-from),normalize(vec3(0.,1.,0.)))*dir;", + "//color+=HUD_COLOR*(vec3(HUDraymarch(from,dir))+.1);", + "}", + + "#endif", + + "vec3 color=raymarch(from,dir); // Raymarch scene", + "color=clamp(color,vec3(.0),vec3(1.));", + "if (backcam>0.) { //if HUD cam, apply post effect", + "color=(.2+pow(length(color),1.7)*.5)*HUD_COLOR", + "*(1.-.5*pow(abs(.025-mod(uv.y*.9,.05))/.025,2.))*.9;", + "}", + + "color=hud.rgb*hud.a+color*(1.-hud.a);//HUD transparency", + + "//color adjustments", + "color=pow(abs(color),vec3(GAMMA))*BRIGHTNESS;", + "color=mix(vec3(length(color)),color,SATURATION);", + "gl_FragColor = vec4(color,1.);", + "}"]; + + +} + +PIXI.SpaceRacingLiteFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); +PIXI.SpaceRacingLiteFilter.prototype.constructor = PIXI.SpaceRacingLiteFilter; + +Object.defineProperty(PIXI.SpaceRacingLiteFilter.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.SpaceRacingLiteFilter(sprite.width, sprite.height, sprite.texture); + + sprite.filters = [filter]; + +} + +function update() { + + filter.iGlobalTime = game.time.totalElapsedSeconds(); + filter.uniforms.iMouse.value.x = game.input.x; + filter.uniforms.iMouse.value.y = game.input.y; + +} + +function render() { +}