diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.frag b/src/core/renderers/webgl/filters/FXAA/FXAA.frag new file mode 100755 index 0000000..2f3b3ae --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.frag @@ -0,0 +1,127 @@ +precision lowp float; + + +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. + +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +varying vec2 vTextureCoord; +varying vec4 vColor; +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + +uniform sampler2D uSampler; + + +void main(void){ + + gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + +} diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.frag b/src/core/renderers/webgl/filters/FXAA/FXAA.frag new file mode 100755 index 0000000..2f3b3ae --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.frag @@ -0,0 +1,127 @@ +precision lowp float; + + +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. + +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +varying vec2 vTextureCoord; +varying vec4 vColor; +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + +uniform sampler2D uSampler; + + +void main(void){ + + gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.vert b/src/core/renderers/webgl/filters/FXAA/FXAA.vert new file mode 100755 index 0000000..b0c1860 --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.vert @@ -0,0 +1,45 @@ + +precision mediump float; + +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; + +uniform mat3 projectionMatrix; +uniform vec2 resolution; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + + +void texcoords(vec2 fragCoord, vec2 resolution, + out vec2 v_rgbNW, out vec2 v_rgbNE, + out vec2 v_rgbSW, out vec2 v_rgbSE, + out vec2 v_rgbM) { + vec2 inverseVP = 1.0 / resolution.xy; + v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; + v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; + v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; + v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; + v_rgbM = vec2(fragCoord * inverseVP); +} + +void main(void){ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); + vResolution = resolution; + + //compute the texture coords and send them to varyings + texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); +} diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.frag b/src/core/renderers/webgl/filters/FXAA/FXAA.frag new file mode 100755 index 0000000..2f3b3ae --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.frag @@ -0,0 +1,127 @@ +precision lowp float; + + +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. + +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +varying vec2 vTextureCoord; +varying vec4 vColor; +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + +uniform sampler2D uSampler; + + +void main(void){ + + gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.vert b/src/core/renderers/webgl/filters/FXAA/FXAA.vert new file mode 100755 index 0000000..b0c1860 --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.vert @@ -0,0 +1,45 @@ + +precision mediump float; + +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; + +uniform mat3 projectionMatrix; +uniform vec2 resolution; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + + +void texcoords(vec2 fragCoord, vec2 resolution, + out vec2 v_rgbNW, out vec2 v_rgbNE, + out vec2 v_rgbSW, out vec2 v_rgbSE, + out vec2 v_rgbM) { + vec2 inverseVP = 1.0 / resolution.xy; + v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; + v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; + v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; + v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; + v_rgbM = vec2(fragCoord * inverseVP); +} + +void main(void){ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); + vResolution = resolution; + + //compute the texture coords and send them to varyings + texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js new file mode 100644 index 0000000..6d5646c --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js @@ -0,0 +1,53 @@ +var AbstractFilter = require('./AbstractFilter'); +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * + * Basic FXAA implementation based on the code on geeks3d.com with the + * modification that the texture2DLod stuff was removed since it's + * unsupported by WebGL. + * + * -- + * From: + * https://github.com/mitsuhiko/webgl-meincraft + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * + */ +function FXAAFilter() +{ + AbstractFilter.call(this, + // vertex shader + fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), + // fragment shader + fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), + // uniforms + { + resolution: { type: 'v2', value: { x: 1, y: 1 } } + } + ); + +} + +FXAAFilter.prototype = Object.create(AbstractFilter.prototype); +FXAAFilter.prototype.constructor = FXAAFilter; +module.exports = FXAAFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +FXAAFilter.prototype.applyFilter = function (renderer, input, output) +{ + var filterManager = renderer.filterManager; + + var shader = this.getShader( renderer ); + // draw the filter... + filterManager.applyFilter(shader, input, output); +}; diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.frag b/src/core/renderers/webgl/filters/FXAA/FXAA.frag new file mode 100755 index 0000000..2f3b3ae --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.frag @@ -0,0 +1,127 @@ +precision lowp float; + + +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. + +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +varying vec2 vTextureCoord; +varying vec4 vColor; +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + +uniform sampler2D uSampler; + + +void main(void){ + + gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.vert b/src/core/renderers/webgl/filters/FXAA/FXAA.vert new file mode 100755 index 0000000..b0c1860 --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.vert @@ -0,0 +1,45 @@ + +precision mediump float; + +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; + +uniform mat3 projectionMatrix; +uniform vec2 resolution; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + + +void texcoords(vec2 fragCoord, vec2 resolution, + out vec2 v_rgbNW, out vec2 v_rgbNE, + out vec2 v_rgbSW, out vec2 v_rgbSE, + out vec2 v_rgbM) { + vec2 inverseVP = 1.0 / resolution.xy; + v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; + v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; + v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; + v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; + v_rgbM = vec2(fragCoord * inverseVP); +} + +void main(void){ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); + vResolution = resolution; + + //compute the texture coords and send them to varyings + texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js new file mode 100644 index 0000000..6d5646c --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js @@ -0,0 +1,53 @@ +var AbstractFilter = require('./AbstractFilter'); +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * + * Basic FXAA implementation based on the code on geeks3d.com with the + * modification that the texture2DLod stuff was removed since it's + * unsupported by WebGL. + * + * -- + * From: + * https://github.com/mitsuhiko/webgl-meincraft + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * + */ +function FXAAFilter() +{ + AbstractFilter.call(this, + // vertex shader + fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), + // fragment shader + fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), + // uniforms + { + resolution: { type: 'v2', value: { x: 1, y: 1 } } + } + ); + +} + +FXAAFilter.prototype = Object.create(AbstractFilter.prototype); +FXAAFilter.prototype.constructor = FXAAFilter; +module.exports = FXAAFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +FXAAFilter.prototype.applyFilter = function (renderer, input, output) +{ + var filterManager = renderer.filterManager; + + var shader = this.getShader( renderer ); + // draw the filter... + filterManager.applyFilter(shader, input, output); +}; diff --git a/src/core/renderers/webgl/filters/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAAFilter.js deleted file mode 100644 index 6d5646c..0000000 --- a/src/core/renderers/webgl/filters/FXAAFilter.js +++ /dev/null @@ -1,53 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'); -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * - * Basic FXAA implementation based on the code on geeks3d.com with the - * modification that the texture2DLod stuff was removed since it's - * unsupported by WebGL. - * - * -- - * From: - * https://github.com/mitsuhiko/webgl-meincraft - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * - */ -function FXAAFilter() -{ - AbstractFilter.call(this, - // vertex shader - fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), - // fragment shader - fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), - // uniforms - { - resolution: { type: 'v2', value: { x: 1, y: 1 } } - } - ); - -} - -FXAAFilter.prototype = Object.create(AbstractFilter.prototype); -FXAAFilter.prototype.constructor = FXAAFilter; -module.exports = FXAAFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -FXAAFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - var shader = this.getShader( renderer ); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.frag b/src/core/renderers/webgl/filters/FXAA/FXAA.frag new file mode 100755 index 0000000..2f3b3ae --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.frag @@ -0,0 +1,127 @@ +precision lowp float; + + +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. + +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +varying vec2 vTextureCoord; +varying vec4 vColor; +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + +uniform sampler2D uSampler; + + +void main(void){ + + gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.vert b/src/core/renderers/webgl/filters/FXAA/FXAA.vert new file mode 100755 index 0000000..b0c1860 --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.vert @@ -0,0 +1,45 @@ + +precision mediump float; + +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; + +uniform mat3 projectionMatrix; +uniform vec2 resolution; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + + +void texcoords(vec2 fragCoord, vec2 resolution, + out vec2 v_rgbNW, out vec2 v_rgbNE, + out vec2 v_rgbSW, out vec2 v_rgbSE, + out vec2 v_rgbM) { + vec2 inverseVP = 1.0 / resolution.xy; + v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; + v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; + v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; + v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; + v_rgbM = vec2(fragCoord * inverseVP); +} + +void main(void){ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); + vResolution = resolution; + + //compute the texture coords and send them to varyings + texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js new file mode 100644 index 0000000..6d5646c --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js @@ -0,0 +1,53 @@ +var AbstractFilter = require('./AbstractFilter'); +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * + * Basic FXAA implementation based on the code on geeks3d.com with the + * modification that the texture2DLod stuff was removed since it's + * unsupported by WebGL. + * + * -- + * From: + * https://github.com/mitsuhiko/webgl-meincraft + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * + */ +function FXAAFilter() +{ + AbstractFilter.call(this, + // vertex shader + fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), + // fragment shader + fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), + // uniforms + { + resolution: { type: 'v2', value: { x: 1, y: 1 } } + } + ); + +} + +FXAAFilter.prototype = Object.create(AbstractFilter.prototype); +FXAAFilter.prototype.constructor = FXAAFilter; +module.exports = FXAAFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +FXAAFilter.prototype.applyFilter = function (renderer, input, output) +{ + var filterManager = renderer.filterManager; + + var shader = this.getShader( renderer ); + // draw the filter... + filterManager.applyFilter(shader, input, output); +}; diff --git a/src/core/renderers/webgl/filters/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAAFilter.js deleted file mode 100644 index 6d5646c..0000000 --- a/src/core/renderers/webgl/filters/FXAAFilter.js +++ /dev/null @@ -1,53 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'); -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * - * Basic FXAA implementation based on the code on geeks3d.com with the - * modification that the texture2DLod stuff was removed since it's - * unsupported by WebGL. - * - * -- - * From: - * https://github.com/mitsuhiko/webgl-meincraft - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * - */ -function FXAAFilter() -{ - AbstractFilter.call(this, - // vertex shader - fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), - // fragment shader - fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), - // uniforms - { - resolution: { type: 'v2', value: { x: 1, y: 1 } } - } - ); - -} - -FXAAFilter.prototype = Object.create(AbstractFilter.prototype); -FXAAFilter.prototype.constructor = FXAAFilter; -module.exports = FXAAFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -FXAAFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - var shader = this.getShader( renderer ); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; diff --git a/src/core/renderers/webgl/filters/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/SpriteMaskFilter.js deleted file mode 100644 index ae08ea9..0000000 --- a/src/core/renderers/webgl/filters/SpriteMaskFilter.js +++ /dev/null @@ -1,95 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'), - math = require('../../../math'); - -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * The SpriteMaskFilter class - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * @param sprite {PIXI.Sprite} the target sprite - */ -function SpriteMaskFilter(sprite) -{ - var maskMatrix = new math.Matrix(); - - AbstractFilter.call(this, - fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), - fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8'), - { - mask: { type: 'sampler2D', value: sprite._texture }, - alpha: { type: 'f', value: 1}, - otherMatrix: { type: 'mat3', value: maskMatrix.toArray(true) } - } - ); - - this.maskSprite = sprite; - this.maskMatrix = maskMatrix; -} - -SpriteMaskFilter.prototype = Object.create(AbstractFilter.prototype); -SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; -module.exports = SpriteMaskFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -SpriteMaskFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - this.uniforms.mask.value = this.maskSprite._texture; - - filterManager.calculateMappedMatrix(input.frame, this.maskSprite, this.maskMatrix); - - this.uniforms.otherMatrix.value = this.maskMatrix.toArray(true); - this.uniforms.alpha.value = this.maskSprite.worldAlpha; - - var shader = this.getShader(renderer); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; - - -Object.defineProperties(SpriteMaskFilter.prototype, { - /** - * The texture used for the displacement map. Must be power of 2 sized texture. - * - * @member {PIXI.Texture} - * @memberof PIXI.SpriteMaskFilter# - */ - map: { - get: function () - { - return this.uniforms.mask.value; - }, - set: function (value) - { - this.uniforms.mask.value = value; - } - }, - - /** - * The offset used to move the displacement map. - * - * @member {PIXI.Point} - * @memberof PIXI.SpriteMaskFilter# - */ - offset: { - get: function() - { - return this.uniforms.offset.value; - }, - set: function(value) - { - this.uniforms.offset.value = value; - } - } -}); diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.frag b/src/core/renderers/webgl/filters/FXAA/FXAA.frag new file mode 100755 index 0000000..2f3b3ae --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.frag @@ -0,0 +1,127 @@ +precision lowp float; + + +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. + +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +varying vec2 vTextureCoord; +varying vec4 vColor; +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + +uniform sampler2D uSampler; + + +void main(void){ + + gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.vert b/src/core/renderers/webgl/filters/FXAA/FXAA.vert new file mode 100755 index 0000000..b0c1860 --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.vert @@ -0,0 +1,45 @@ + +precision mediump float; + +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; + +uniform mat3 projectionMatrix; +uniform vec2 resolution; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + + +void texcoords(vec2 fragCoord, vec2 resolution, + out vec2 v_rgbNW, out vec2 v_rgbNE, + out vec2 v_rgbSW, out vec2 v_rgbSE, + out vec2 v_rgbM) { + vec2 inverseVP = 1.0 / resolution.xy; + v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; + v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; + v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; + v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; + v_rgbM = vec2(fragCoord * inverseVP); +} + +void main(void){ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); + vResolution = resolution; + + //compute the texture coords and send them to varyings + texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js new file mode 100644 index 0000000..6d5646c --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js @@ -0,0 +1,53 @@ +var AbstractFilter = require('./AbstractFilter'); +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * + * Basic FXAA implementation based on the code on geeks3d.com with the + * modification that the texture2DLod stuff was removed since it's + * unsupported by WebGL. + * + * -- + * From: + * https://github.com/mitsuhiko/webgl-meincraft + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * + */ +function FXAAFilter() +{ + AbstractFilter.call(this, + // vertex shader + fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), + // fragment shader + fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), + // uniforms + { + resolution: { type: 'v2', value: { x: 1, y: 1 } } + } + ); + +} + +FXAAFilter.prototype = Object.create(AbstractFilter.prototype); +FXAAFilter.prototype.constructor = FXAAFilter; +module.exports = FXAAFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +FXAAFilter.prototype.applyFilter = function (renderer, input, output) +{ + var filterManager = renderer.filterManager; + + var shader = this.getShader( renderer ); + // draw the filter... + filterManager.applyFilter(shader, input, output); +}; diff --git a/src/core/renderers/webgl/filters/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAAFilter.js deleted file mode 100644 index 6d5646c..0000000 --- a/src/core/renderers/webgl/filters/FXAAFilter.js +++ /dev/null @@ -1,53 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'); -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * - * Basic FXAA implementation based on the code on geeks3d.com with the - * modification that the texture2DLod stuff was removed since it's - * unsupported by WebGL. - * - * -- - * From: - * https://github.com/mitsuhiko/webgl-meincraft - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * - */ -function FXAAFilter() -{ - AbstractFilter.call(this, - // vertex shader - fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), - // fragment shader - fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), - // uniforms - { - resolution: { type: 'v2', value: { x: 1, y: 1 } } - } - ); - -} - -FXAAFilter.prototype = Object.create(AbstractFilter.prototype); -FXAAFilter.prototype.constructor = FXAAFilter; -module.exports = FXAAFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -FXAAFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - var shader = this.getShader( renderer ); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; diff --git a/src/core/renderers/webgl/filters/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/SpriteMaskFilter.js deleted file mode 100644 index ae08ea9..0000000 --- a/src/core/renderers/webgl/filters/SpriteMaskFilter.js +++ /dev/null @@ -1,95 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'), - math = require('../../../math'); - -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * The SpriteMaskFilter class - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * @param sprite {PIXI.Sprite} the target sprite - */ -function SpriteMaskFilter(sprite) -{ - var maskMatrix = new math.Matrix(); - - AbstractFilter.call(this, - fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), - fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8'), - { - mask: { type: 'sampler2D', value: sprite._texture }, - alpha: { type: 'f', value: 1}, - otherMatrix: { type: 'mat3', value: maskMatrix.toArray(true) } - } - ); - - this.maskSprite = sprite; - this.maskMatrix = maskMatrix; -} - -SpriteMaskFilter.prototype = Object.create(AbstractFilter.prototype); -SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; -module.exports = SpriteMaskFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -SpriteMaskFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - this.uniforms.mask.value = this.maskSprite._texture; - - filterManager.calculateMappedMatrix(input.frame, this.maskSprite, this.maskMatrix); - - this.uniforms.otherMatrix.value = this.maskMatrix.toArray(true); - this.uniforms.alpha.value = this.maskSprite.worldAlpha; - - var shader = this.getShader(renderer); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; - - -Object.defineProperties(SpriteMaskFilter.prototype, { - /** - * The texture used for the displacement map. Must be power of 2 sized texture. - * - * @member {PIXI.Texture} - * @memberof PIXI.SpriteMaskFilter# - */ - map: { - get: function () - { - return this.uniforms.mask.value; - }, - set: function (value) - { - this.uniforms.mask.value = value; - } - }, - - /** - * The offset used to move the displacement map. - * - * @member {PIXI.Point} - * @memberof PIXI.SpriteMaskFilter# - */ - offset: { - get: function() - { - return this.uniforms.offset.value; - }, - set: function(value) - { - this.uniforms.offset.value = value; - } - } -}); diff --git a/src/core/renderers/webgl/filters/defaultValue.js b/src/core/renderers/webgl/filters/defaultValue.js deleted file mode 100644 index bcb27f5..0000000 --- a/src/core/renderers/webgl/filters/defaultValue.js +++ /dev/null @@ -1,74 +0,0 @@ - - -var defaultValue = function(type, size) -{ - switch (type) - { - case 'float': - return 0; - - case 'vec2': - return new Float32Array(2 * size); - - case 'vec3': - return new Float32Array(3 * size); - - case 'vec4': - return new Float32Array(4 * size); - - case 'int': - case 'sampler2D': - return 0; - - case 'ivec2': - return new Int32Array(2 * size); - - case 'ivec3': - return new Int32Array(3 * size); - - case 'ivec4': - return new Int32Array(4 * size); - - case 'bool': - return false; - - case 'bvec2': - - return booleanArray( 2 * size); - - case 'bvec3': - return booleanArray(3 * size); - - case 'bvec4': - return booleanArray(4 * size); - - case 'mat2': - return new Float32Array([1, 0 - ,0, 1]); - - case 'mat3': - return new Float32Array([1, 0, 0 - ,0, 1, 0 - ,0, 0, 1]); - - case 'mat4': - return new Float32Array([1, 0, 0, 0 - ,0, 1, 0, 0 - ,0, 0, 1, 0 - ,0, 0, 0, 1]); - } -} - -var booleanArray = function(size) -{ - var array = new Array(size); - - for (var i = 0; i < array.length; i++) - { - array[i] = false; - }; - - return array; -} - -module.exports = defaultValue; diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.frag b/src/core/renderers/webgl/filters/FXAA/FXAA.frag new file mode 100755 index 0000000..2f3b3ae --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.frag @@ -0,0 +1,127 @@ +precision lowp float; + + +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. + +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +varying vec2 vTextureCoord; +varying vec4 vColor; +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + +uniform sampler2D uSampler; + + +void main(void){ + + gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.vert b/src/core/renderers/webgl/filters/FXAA/FXAA.vert new file mode 100755 index 0000000..b0c1860 --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.vert @@ -0,0 +1,45 @@ + +precision mediump float; + +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; + +uniform mat3 projectionMatrix; +uniform vec2 resolution; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + + +void texcoords(vec2 fragCoord, vec2 resolution, + out vec2 v_rgbNW, out vec2 v_rgbNE, + out vec2 v_rgbSW, out vec2 v_rgbSE, + out vec2 v_rgbM) { + vec2 inverseVP = 1.0 / resolution.xy; + v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; + v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; + v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; + v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; + v_rgbM = vec2(fragCoord * inverseVP); +} + +void main(void){ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); + vResolution = resolution; + + //compute the texture coords and send them to varyings + texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js new file mode 100644 index 0000000..6d5646c --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js @@ -0,0 +1,53 @@ +var AbstractFilter = require('./AbstractFilter'); +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * + * Basic FXAA implementation based on the code on geeks3d.com with the + * modification that the texture2DLod stuff was removed since it's + * unsupported by WebGL. + * + * -- + * From: + * https://github.com/mitsuhiko/webgl-meincraft + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * + */ +function FXAAFilter() +{ + AbstractFilter.call(this, + // vertex shader + fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), + // fragment shader + fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), + // uniforms + { + resolution: { type: 'v2', value: { x: 1, y: 1 } } + } + ); + +} + +FXAAFilter.prototype = Object.create(AbstractFilter.prototype); +FXAAFilter.prototype.constructor = FXAAFilter; +module.exports = FXAAFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +FXAAFilter.prototype.applyFilter = function (renderer, input, output) +{ + var filterManager = renderer.filterManager; + + var shader = this.getShader( renderer ); + // draw the filter... + filterManager.applyFilter(shader, input, output); +}; diff --git a/src/core/renderers/webgl/filters/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAAFilter.js deleted file mode 100644 index 6d5646c..0000000 --- a/src/core/renderers/webgl/filters/FXAAFilter.js +++ /dev/null @@ -1,53 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'); -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * - * Basic FXAA implementation based on the code on geeks3d.com with the - * modification that the texture2DLod stuff was removed since it's - * unsupported by WebGL. - * - * -- - * From: - * https://github.com/mitsuhiko/webgl-meincraft - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * - */ -function FXAAFilter() -{ - AbstractFilter.call(this, - // vertex shader - fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), - // fragment shader - fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), - // uniforms - { - resolution: { type: 'v2', value: { x: 1, y: 1 } } - } - ); - -} - -FXAAFilter.prototype = Object.create(AbstractFilter.prototype); -FXAAFilter.prototype.constructor = FXAAFilter; -module.exports = FXAAFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -FXAAFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - var shader = this.getShader( renderer ); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; diff --git a/src/core/renderers/webgl/filters/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/SpriteMaskFilter.js deleted file mode 100644 index ae08ea9..0000000 --- a/src/core/renderers/webgl/filters/SpriteMaskFilter.js +++ /dev/null @@ -1,95 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'), - math = require('../../../math'); - -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * The SpriteMaskFilter class - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * @param sprite {PIXI.Sprite} the target sprite - */ -function SpriteMaskFilter(sprite) -{ - var maskMatrix = new math.Matrix(); - - AbstractFilter.call(this, - fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), - fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8'), - { - mask: { type: 'sampler2D', value: sprite._texture }, - alpha: { type: 'f', value: 1}, - otherMatrix: { type: 'mat3', value: maskMatrix.toArray(true) } - } - ); - - this.maskSprite = sprite; - this.maskMatrix = maskMatrix; -} - -SpriteMaskFilter.prototype = Object.create(AbstractFilter.prototype); -SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; -module.exports = SpriteMaskFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -SpriteMaskFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - this.uniforms.mask.value = this.maskSprite._texture; - - filterManager.calculateMappedMatrix(input.frame, this.maskSprite, this.maskMatrix); - - this.uniforms.otherMatrix.value = this.maskMatrix.toArray(true); - this.uniforms.alpha.value = this.maskSprite.worldAlpha; - - var shader = this.getShader(renderer); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; - - -Object.defineProperties(SpriteMaskFilter.prototype, { - /** - * The texture used for the displacement map. Must be power of 2 sized texture. - * - * @member {PIXI.Texture} - * @memberof PIXI.SpriteMaskFilter# - */ - map: { - get: function () - { - return this.uniforms.mask.value; - }, - set: function (value) - { - this.uniforms.mask.value = value; - } - }, - - /** - * The offset used to move the displacement map. - * - * @member {PIXI.Point} - * @memberof PIXI.SpriteMaskFilter# - */ - offset: { - get: function() - { - return this.uniforms.offset.value; - }, - set: function(value) - { - this.uniforms.offset.value = value; - } - } -}); diff --git a/src/core/renderers/webgl/filters/defaultValue.js b/src/core/renderers/webgl/filters/defaultValue.js deleted file mode 100644 index bcb27f5..0000000 --- a/src/core/renderers/webgl/filters/defaultValue.js +++ /dev/null @@ -1,74 +0,0 @@ - - -var defaultValue = function(type, size) -{ - switch (type) - { - case 'float': - return 0; - - case 'vec2': - return new Float32Array(2 * size); - - case 'vec3': - return new Float32Array(3 * size); - - case 'vec4': - return new Float32Array(4 * size); - - case 'int': - case 'sampler2D': - return 0; - - case 'ivec2': - return new Int32Array(2 * size); - - case 'ivec3': - return new Int32Array(3 * size); - - case 'ivec4': - return new Int32Array(4 * size); - - case 'bool': - return false; - - case 'bvec2': - - return booleanArray( 2 * size); - - case 'bvec3': - return booleanArray(3 * size); - - case 'bvec4': - return booleanArray(4 * size); - - case 'mat2': - return new Float32Array([1, 0 - ,0, 1]); - - case 'mat3': - return new Float32Array([1, 0, 0 - ,0, 1, 0 - ,0, 0, 1]); - - case 'mat4': - return new Float32Array([1, 0, 0, 0 - ,0, 1, 0, 0 - ,0, 0, 1, 0 - ,0, 0, 0, 1]); - } -} - -var booleanArray = function(size) -{ - var array = new Array(size); - - for (var i = 0; i < array.length; i++) - { - array[i] = false; - }; - - return array; -} - -module.exports = defaultValue; diff --git a/src/core/renderers/webgl/filters/shaderParser.js b/src/core/renderers/webgl/filters/shaderParser.js deleted file mode 100644 index 9a94af6..0000000 --- a/src/core/renderers/webgl/filters/shaderParser.js +++ /dev/null @@ -1,109 +0,0 @@ - -/** - * The default vertex shader source - * - * @static - * @constant - */ -var defaultVertexSrc = [ - 'precision lowp float;', - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - - 'uniform mat3 projectionMatrix;', - 'uniform mat3 otherMatrix;', - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vFilterCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy;', - ' vTextureCoord = aTextureCoord ;', - '}' -].join('\n'); - -/** - * The default fragment shader source - * - * @static - * @constant - */ -var defaultFragmentSrc = [ - 'precision lowp float;', - - 'struct Matty{', - ' float some;', - ' float dohave;', - 'float them;', - '};', - - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - 'uniform sampler2D uSampler;', - 'uniform sampler2D filterSampler;', - 'uniform Matty thing;', - - 'void main(void){', - ' vec4 masky = texture2D(filterSampler, vFilterCoord);', - ' vec4 sample = texture2D(uSampler, vTextureCoord);', - ' vec4 color;', - ' if(mod(vFilterCoord.x, 1.0) > 0.5){', - ' ', - ' color = vec4(1.0, 0.0, 0.0, 1.0) + thing.some;', - ' }', - ' else', - ' {', - ' color = vec4(0.0, 1.0, 0.0, 1.0) ;', - ' }', - // ' gl_FragColor = vec4(mod(vFilterCoord.x, 1.5), vFilterCoord.y,0.0,1.0);', - ' gl_FragColor = mix(sample, masky, 0.5);', - ' gl_FragColor *= sample.a;', - '}' -].join('\n'); - -//clean out white space tabs -var lines = defaultFragmentSrc.replace(/\s+/g,' ') - .split(/\s*;\s*/); - -function extractUniforms(vertexSrc, fragmentSrc) -{ - var fragUniforms = extractUniformsFromString(defaultFragmentSrc); - var vertUniforms = extractUniformsFromString(defaultVertexSrc); - - return Object.assign(fragUniforms, vertUniforms); -} - -function mergeObject(object1, object2) -{ - return Object.assign({}, object1, object2); -} - - -function extractUniformsFromString(string) -{ - var uniforms = {}; - - // clean the lines a little - remove extra spaces / teabs etc - // then split along ';' - var lines = string.replace(/\s+/g,' ') - .split(/\s*;\s*/); - - - // loop through.. - for (var i = 0; i < lines.length; i++) - { - var line = lines[i].trim(); - - if(line.indexOf('uniform') > -1) - { - var splitLine = line.split(' '); - var type = splitLine[1]; - var name = splitLine[2]; - console.log(name + " is of type " + type); - uniforms[name] = 0; - } - - return uniforms; - }; -} -//console.log(lines); diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.frag b/src/core/renderers/webgl/filters/FXAA/FXAA.frag new file mode 100755 index 0000000..2f3b3ae --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.frag @@ -0,0 +1,127 @@ +precision lowp float; + + +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. + +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +varying vec2 vTextureCoord; +varying vec4 vColor; +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + +uniform sampler2D uSampler; + + +void main(void){ + + gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.vert b/src/core/renderers/webgl/filters/FXAA/FXAA.vert new file mode 100755 index 0000000..b0c1860 --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.vert @@ -0,0 +1,45 @@ + +precision mediump float; + +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; + +uniform mat3 projectionMatrix; +uniform vec2 resolution; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + + +void texcoords(vec2 fragCoord, vec2 resolution, + out vec2 v_rgbNW, out vec2 v_rgbNE, + out vec2 v_rgbSW, out vec2 v_rgbSE, + out vec2 v_rgbM) { + vec2 inverseVP = 1.0 / resolution.xy; + v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; + v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; + v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; + v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; + v_rgbM = vec2(fragCoord * inverseVP); +} + +void main(void){ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); + vResolution = resolution; + + //compute the texture coords and send them to varyings + texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js new file mode 100644 index 0000000..6d5646c --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js @@ -0,0 +1,53 @@ +var AbstractFilter = require('./AbstractFilter'); +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * + * Basic FXAA implementation based on the code on geeks3d.com with the + * modification that the texture2DLod stuff was removed since it's + * unsupported by WebGL. + * + * -- + * From: + * https://github.com/mitsuhiko/webgl-meincraft + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * + */ +function FXAAFilter() +{ + AbstractFilter.call(this, + // vertex shader + fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), + // fragment shader + fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), + // uniforms + { + resolution: { type: 'v2', value: { x: 1, y: 1 } } + } + ); + +} + +FXAAFilter.prototype = Object.create(AbstractFilter.prototype); +FXAAFilter.prototype.constructor = FXAAFilter; +module.exports = FXAAFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +FXAAFilter.prototype.applyFilter = function (renderer, input, output) +{ + var filterManager = renderer.filterManager; + + var shader = this.getShader( renderer ); + // draw the filter... + filterManager.applyFilter(shader, input, output); +}; diff --git a/src/core/renderers/webgl/filters/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAAFilter.js deleted file mode 100644 index 6d5646c..0000000 --- a/src/core/renderers/webgl/filters/FXAAFilter.js +++ /dev/null @@ -1,53 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'); -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * - * Basic FXAA implementation based on the code on geeks3d.com with the - * modification that the texture2DLod stuff was removed since it's - * unsupported by WebGL. - * - * -- - * From: - * https://github.com/mitsuhiko/webgl-meincraft - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * - */ -function FXAAFilter() -{ - AbstractFilter.call(this, - // vertex shader - fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), - // fragment shader - fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), - // uniforms - { - resolution: { type: 'v2', value: { x: 1, y: 1 } } - } - ); - -} - -FXAAFilter.prototype = Object.create(AbstractFilter.prototype); -FXAAFilter.prototype.constructor = FXAAFilter; -module.exports = FXAAFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -FXAAFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - var shader = this.getShader( renderer ); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; diff --git a/src/core/renderers/webgl/filters/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/SpriteMaskFilter.js deleted file mode 100644 index ae08ea9..0000000 --- a/src/core/renderers/webgl/filters/SpriteMaskFilter.js +++ /dev/null @@ -1,95 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'), - math = require('../../../math'); - -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * The SpriteMaskFilter class - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * @param sprite {PIXI.Sprite} the target sprite - */ -function SpriteMaskFilter(sprite) -{ - var maskMatrix = new math.Matrix(); - - AbstractFilter.call(this, - fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), - fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8'), - { - mask: { type: 'sampler2D', value: sprite._texture }, - alpha: { type: 'f', value: 1}, - otherMatrix: { type: 'mat3', value: maskMatrix.toArray(true) } - } - ); - - this.maskSprite = sprite; - this.maskMatrix = maskMatrix; -} - -SpriteMaskFilter.prototype = Object.create(AbstractFilter.prototype); -SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; -module.exports = SpriteMaskFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -SpriteMaskFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - this.uniforms.mask.value = this.maskSprite._texture; - - filterManager.calculateMappedMatrix(input.frame, this.maskSprite, this.maskMatrix); - - this.uniforms.otherMatrix.value = this.maskMatrix.toArray(true); - this.uniforms.alpha.value = this.maskSprite.worldAlpha; - - var shader = this.getShader(renderer); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; - - -Object.defineProperties(SpriteMaskFilter.prototype, { - /** - * The texture used for the displacement map. Must be power of 2 sized texture. - * - * @member {PIXI.Texture} - * @memberof PIXI.SpriteMaskFilter# - */ - map: { - get: function () - { - return this.uniforms.mask.value; - }, - set: function (value) - { - this.uniforms.mask.value = value; - } - }, - - /** - * The offset used to move the displacement map. - * - * @member {PIXI.Point} - * @memberof PIXI.SpriteMaskFilter# - */ - offset: { - get: function() - { - return this.uniforms.offset.value; - }, - set: function(value) - { - this.uniforms.offset.value = value; - } - } -}); diff --git a/src/core/renderers/webgl/filters/defaultValue.js b/src/core/renderers/webgl/filters/defaultValue.js deleted file mode 100644 index bcb27f5..0000000 --- a/src/core/renderers/webgl/filters/defaultValue.js +++ /dev/null @@ -1,74 +0,0 @@ - - -var defaultValue = function(type, size) -{ - switch (type) - { - case 'float': - return 0; - - case 'vec2': - return new Float32Array(2 * size); - - case 'vec3': - return new Float32Array(3 * size); - - case 'vec4': - return new Float32Array(4 * size); - - case 'int': - case 'sampler2D': - return 0; - - case 'ivec2': - return new Int32Array(2 * size); - - case 'ivec3': - return new Int32Array(3 * size); - - case 'ivec4': - return new Int32Array(4 * size); - - case 'bool': - return false; - - case 'bvec2': - - return booleanArray( 2 * size); - - case 'bvec3': - return booleanArray(3 * size); - - case 'bvec4': - return booleanArray(4 * size); - - case 'mat2': - return new Float32Array([1, 0 - ,0, 1]); - - case 'mat3': - return new Float32Array([1, 0, 0 - ,0, 1, 0 - ,0, 0, 1]); - - case 'mat4': - return new Float32Array([1, 0, 0, 0 - ,0, 1, 0, 0 - ,0, 0, 1, 0 - ,0, 0, 0, 1]); - } -} - -var booleanArray = function(size) -{ - var array = new Array(size); - - for (var i = 0; i < array.length; i++) - { - array[i] = false; - }; - - return array; -} - -module.exports = defaultValue; diff --git a/src/core/renderers/webgl/filters/shaderParser.js b/src/core/renderers/webgl/filters/shaderParser.js deleted file mode 100644 index 9a94af6..0000000 --- a/src/core/renderers/webgl/filters/shaderParser.js +++ /dev/null @@ -1,109 +0,0 @@ - -/** - * The default vertex shader source - * - * @static - * @constant - */ -var defaultVertexSrc = [ - 'precision lowp float;', - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - - 'uniform mat3 projectionMatrix;', - 'uniform mat3 otherMatrix;', - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vFilterCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy;', - ' vTextureCoord = aTextureCoord ;', - '}' -].join('\n'); - -/** - * The default fragment shader source - * - * @static - * @constant - */ -var defaultFragmentSrc = [ - 'precision lowp float;', - - 'struct Matty{', - ' float some;', - ' float dohave;', - 'float them;', - '};', - - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - 'uniform sampler2D uSampler;', - 'uniform sampler2D filterSampler;', - 'uniform Matty thing;', - - 'void main(void){', - ' vec4 masky = texture2D(filterSampler, vFilterCoord);', - ' vec4 sample = texture2D(uSampler, vTextureCoord);', - ' vec4 color;', - ' if(mod(vFilterCoord.x, 1.0) > 0.5){', - ' ', - ' color = vec4(1.0, 0.0, 0.0, 1.0) + thing.some;', - ' }', - ' else', - ' {', - ' color = vec4(0.0, 1.0, 0.0, 1.0) ;', - ' }', - // ' gl_FragColor = vec4(mod(vFilterCoord.x, 1.5), vFilterCoord.y,0.0,1.0);', - ' gl_FragColor = mix(sample, masky, 0.5);', - ' gl_FragColor *= sample.a;', - '}' -].join('\n'); - -//clean out white space tabs -var lines = defaultFragmentSrc.replace(/\s+/g,' ') - .split(/\s*;\s*/); - -function extractUniforms(vertexSrc, fragmentSrc) -{ - var fragUniforms = extractUniformsFromString(defaultFragmentSrc); - var vertUniforms = extractUniformsFromString(defaultVertexSrc); - - return Object.assign(fragUniforms, vertUniforms); -} - -function mergeObject(object1, object2) -{ - return Object.assign({}, object1, object2); -} - - -function extractUniformsFromString(string) -{ - var uniforms = {}; - - // clean the lines a little - remove extra spaces / teabs etc - // then split along ';' - var lines = string.replace(/\s+/g,' ') - .split(/\s*;\s*/); - - - // loop through.. - for (var i = 0; i < lines.length; i++) - { - var line = lines[i].trim(); - - if(line.indexOf('uniform') > -1) - { - var splitLine = line.split(' '); - var type = splitLine[1]; - var name = splitLine[2]; - console.log(name + " is of type " + type); - uniforms[name] = 0; - } - - return uniforms; - }; -} -//console.log(lines); diff --git a/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js new file mode 100644 index 0000000..f961c94 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js @@ -0,0 +1,50 @@ +var Filter = require('../Filter'), + math = require('../../../../math'); + +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * The SpriteMaskFilter class + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * @param sprite {PIXI.Sprite} the target sprite + */ +function SpriteMaskFilter(sprite) +{ + var maskMatrix = new math.Matrix(); + + Filter.call(this, + fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), + fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8') + ); + + sprite.renderable = false; + + this.maskSprite = sprite; + this.maskMatrix = maskMatrix; +} + +SpriteMaskFilter.prototype = Object.create(Filter.prototype); +SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; +module.exports = SpriteMaskFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +SpriteMaskFilter.prototype.apply = function (filterManager, input, output) +{ + var maskSprite = this.maskSprite; + + this.uniforms.mask = maskSprite._texture; + this.uniforms.otherMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, maskSprite ); + this.uniforms.alpha = maskSprite.worldAlpha; + + filterManager.applyFilter(this, input, output); +}; diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.frag b/src/core/renderers/webgl/filters/FXAA/FXAA.frag new file mode 100755 index 0000000..2f3b3ae --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.frag @@ -0,0 +1,127 @@ +precision lowp float; + + +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. + +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +varying vec2 vTextureCoord; +varying vec4 vColor; +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + +uniform sampler2D uSampler; + + +void main(void){ + + gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.vert b/src/core/renderers/webgl/filters/FXAA/FXAA.vert new file mode 100755 index 0000000..b0c1860 --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.vert @@ -0,0 +1,45 @@ + +precision mediump float; + +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; + +uniform mat3 projectionMatrix; +uniform vec2 resolution; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + + +void texcoords(vec2 fragCoord, vec2 resolution, + out vec2 v_rgbNW, out vec2 v_rgbNE, + out vec2 v_rgbSW, out vec2 v_rgbSE, + out vec2 v_rgbM) { + vec2 inverseVP = 1.0 / resolution.xy; + v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; + v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; + v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; + v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; + v_rgbM = vec2(fragCoord * inverseVP); +} + +void main(void){ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); + vResolution = resolution; + + //compute the texture coords and send them to varyings + texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js new file mode 100644 index 0000000..6d5646c --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js @@ -0,0 +1,53 @@ +var AbstractFilter = require('./AbstractFilter'); +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * + * Basic FXAA implementation based on the code on geeks3d.com with the + * modification that the texture2DLod stuff was removed since it's + * unsupported by WebGL. + * + * -- + * From: + * https://github.com/mitsuhiko/webgl-meincraft + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * + */ +function FXAAFilter() +{ + AbstractFilter.call(this, + // vertex shader + fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), + // fragment shader + fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), + // uniforms + { + resolution: { type: 'v2', value: { x: 1, y: 1 } } + } + ); + +} + +FXAAFilter.prototype = Object.create(AbstractFilter.prototype); +FXAAFilter.prototype.constructor = FXAAFilter; +module.exports = FXAAFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +FXAAFilter.prototype.applyFilter = function (renderer, input, output) +{ + var filterManager = renderer.filterManager; + + var shader = this.getShader( renderer ); + // draw the filter... + filterManager.applyFilter(shader, input, output); +}; diff --git a/src/core/renderers/webgl/filters/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAAFilter.js deleted file mode 100644 index 6d5646c..0000000 --- a/src/core/renderers/webgl/filters/FXAAFilter.js +++ /dev/null @@ -1,53 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'); -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * - * Basic FXAA implementation based on the code on geeks3d.com with the - * modification that the texture2DLod stuff was removed since it's - * unsupported by WebGL. - * - * -- - * From: - * https://github.com/mitsuhiko/webgl-meincraft - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * - */ -function FXAAFilter() -{ - AbstractFilter.call(this, - // vertex shader - fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), - // fragment shader - fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), - // uniforms - { - resolution: { type: 'v2', value: { x: 1, y: 1 } } - } - ); - -} - -FXAAFilter.prototype = Object.create(AbstractFilter.prototype); -FXAAFilter.prototype.constructor = FXAAFilter; -module.exports = FXAAFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -FXAAFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - var shader = this.getShader( renderer ); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; diff --git a/src/core/renderers/webgl/filters/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/SpriteMaskFilter.js deleted file mode 100644 index ae08ea9..0000000 --- a/src/core/renderers/webgl/filters/SpriteMaskFilter.js +++ /dev/null @@ -1,95 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'), - math = require('../../../math'); - -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * The SpriteMaskFilter class - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * @param sprite {PIXI.Sprite} the target sprite - */ -function SpriteMaskFilter(sprite) -{ - var maskMatrix = new math.Matrix(); - - AbstractFilter.call(this, - fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), - fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8'), - { - mask: { type: 'sampler2D', value: sprite._texture }, - alpha: { type: 'f', value: 1}, - otherMatrix: { type: 'mat3', value: maskMatrix.toArray(true) } - } - ); - - this.maskSprite = sprite; - this.maskMatrix = maskMatrix; -} - -SpriteMaskFilter.prototype = Object.create(AbstractFilter.prototype); -SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; -module.exports = SpriteMaskFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -SpriteMaskFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - this.uniforms.mask.value = this.maskSprite._texture; - - filterManager.calculateMappedMatrix(input.frame, this.maskSprite, this.maskMatrix); - - this.uniforms.otherMatrix.value = this.maskMatrix.toArray(true); - this.uniforms.alpha.value = this.maskSprite.worldAlpha; - - var shader = this.getShader(renderer); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; - - -Object.defineProperties(SpriteMaskFilter.prototype, { - /** - * The texture used for the displacement map. Must be power of 2 sized texture. - * - * @member {PIXI.Texture} - * @memberof PIXI.SpriteMaskFilter# - */ - map: { - get: function () - { - return this.uniforms.mask.value; - }, - set: function (value) - { - this.uniforms.mask.value = value; - } - }, - - /** - * The offset used to move the displacement map. - * - * @member {PIXI.Point} - * @memberof PIXI.SpriteMaskFilter# - */ - offset: { - get: function() - { - return this.uniforms.offset.value; - }, - set: function(value) - { - this.uniforms.offset.value = value; - } - } -}); diff --git a/src/core/renderers/webgl/filters/defaultValue.js b/src/core/renderers/webgl/filters/defaultValue.js deleted file mode 100644 index bcb27f5..0000000 --- a/src/core/renderers/webgl/filters/defaultValue.js +++ /dev/null @@ -1,74 +0,0 @@ - - -var defaultValue = function(type, size) -{ - switch (type) - { - case 'float': - return 0; - - case 'vec2': - return new Float32Array(2 * size); - - case 'vec3': - return new Float32Array(3 * size); - - case 'vec4': - return new Float32Array(4 * size); - - case 'int': - case 'sampler2D': - return 0; - - case 'ivec2': - return new Int32Array(2 * size); - - case 'ivec3': - return new Int32Array(3 * size); - - case 'ivec4': - return new Int32Array(4 * size); - - case 'bool': - return false; - - case 'bvec2': - - return booleanArray( 2 * size); - - case 'bvec3': - return booleanArray(3 * size); - - case 'bvec4': - return booleanArray(4 * size); - - case 'mat2': - return new Float32Array([1, 0 - ,0, 1]); - - case 'mat3': - return new Float32Array([1, 0, 0 - ,0, 1, 0 - ,0, 0, 1]); - - case 'mat4': - return new Float32Array([1, 0, 0, 0 - ,0, 1, 0, 0 - ,0, 0, 1, 0 - ,0, 0, 0, 1]); - } -} - -var booleanArray = function(size) -{ - var array = new Array(size); - - for (var i = 0; i < array.length; i++) - { - array[i] = false; - }; - - return array; -} - -module.exports = defaultValue; diff --git a/src/core/renderers/webgl/filters/shaderParser.js b/src/core/renderers/webgl/filters/shaderParser.js deleted file mode 100644 index 9a94af6..0000000 --- a/src/core/renderers/webgl/filters/shaderParser.js +++ /dev/null @@ -1,109 +0,0 @@ - -/** - * The default vertex shader source - * - * @static - * @constant - */ -var defaultVertexSrc = [ - 'precision lowp float;', - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - - 'uniform mat3 projectionMatrix;', - 'uniform mat3 otherMatrix;', - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vFilterCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy;', - ' vTextureCoord = aTextureCoord ;', - '}' -].join('\n'); - -/** - * The default fragment shader source - * - * @static - * @constant - */ -var defaultFragmentSrc = [ - 'precision lowp float;', - - 'struct Matty{', - ' float some;', - ' float dohave;', - 'float them;', - '};', - - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - 'uniform sampler2D uSampler;', - 'uniform sampler2D filterSampler;', - 'uniform Matty thing;', - - 'void main(void){', - ' vec4 masky = texture2D(filterSampler, vFilterCoord);', - ' vec4 sample = texture2D(uSampler, vTextureCoord);', - ' vec4 color;', - ' if(mod(vFilterCoord.x, 1.0) > 0.5){', - ' ', - ' color = vec4(1.0, 0.0, 0.0, 1.0) + thing.some;', - ' }', - ' else', - ' {', - ' color = vec4(0.0, 1.0, 0.0, 1.0) ;', - ' }', - // ' gl_FragColor = vec4(mod(vFilterCoord.x, 1.5), vFilterCoord.y,0.0,1.0);', - ' gl_FragColor = mix(sample, masky, 0.5);', - ' gl_FragColor *= sample.a;', - '}' -].join('\n'); - -//clean out white space tabs -var lines = defaultFragmentSrc.replace(/\s+/g,' ') - .split(/\s*;\s*/); - -function extractUniforms(vertexSrc, fragmentSrc) -{ - var fragUniforms = extractUniformsFromString(defaultFragmentSrc); - var vertUniforms = extractUniformsFromString(defaultVertexSrc); - - return Object.assign(fragUniforms, vertUniforms); -} - -function mergeObject(object1, object2) -{ - return Object.assign({}, object1, object2); -} - - -function extractUniformsFromString(string) -{ - var uniforms = {}; - - // clean the lines a little - remove extra spaces / teabs etc - // then split along ';' - var lines = string.replace(/\s+/g,' ') - .split(/\s*;\s*/); - - - // loop through.. - for (var i = 0; i < lines.length; i++) - { - var line = lines[i].trim(); - - if(line.indexOf('uniform') > -1) - { - var splitLine = line.split(' '); - var type = splitLine[1]; - var name = splitLine[2]; - console.log(name + " is of type " + type); - uniforms[name] = 0; - } - - return uniforms; - }; -} -//console.log(lines); diff --git a/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js new file mode 100644 index 0000000..f961c94 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js @@ -0,0 +1,50 @@ +var Filter = require('../Filter'), + math = require('../../../../math'); + +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * The SpriteMaskFilter class + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * @param sprite {PIXI.Sprite} the target sprite + */ +function SpriteMaskFilter(sprite) +{ + var maskMatrix = new math.Matrix(); + + Filter.call(this, + fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), + fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8') + ); + + sprite.renderable = false; + + this.maskSprite = sprite; + this.maskMatrix = maskMatrix; +} + +SpriteMaskFilter.prototype = Object.create(Filter.prototype); +SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; +module.exports = SpriteMaskFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +SpriteMaskFilter.prototype.apply = function (filterManager, input, output) +{ + var maskSprite = this.maskSprite; + + this.uniforms.mask = maskSprite._texture; + this.uniforms.otherMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, maskSprite ); + this.uniforms.alpha = maskSprite.worldAlpha; + + filterManager.applyFilter(this, input, output); +}; diff --git a/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag new file mode 100644 index 0000000..690dab0 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag @@ -0,0 +1,20 @@ +precision lowp float; + +varying vec2 vMaskCoord; +varying vec2 vTextureCoord; + +uniform sampler2D uSampler; +uniform float alpha; +uniform sampler2D mask; + +void main(void) +{ + // check clip! this will stop the mask bleeding out from the edges + vec2 text = abs( vMaskCoord - 0.5 ); + text = step(0.5, text); + float clip = 1.0 - max(text.y, text.x); + vec4 original = texture2D(uSampler, vTextureCoord); + vec4 masky = texture2D(mask, vMaskCoord); + original *= (masky.r * masky.a * alpha * clip); + gl_FragColor = original; +} diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.frag b/src/core/renderers/webgl/filters/FXAA/FXAA.frag new file mode 100755 index 0000000..2f3b3ae --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.frag @@ -0,0 +1,127 @@ +precision lowp float; + + +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. + +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +varying vec2 vTextureCoord; +varying vec4 vColor; +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + +uniform sampler2D uSampler; + + +void main(void){ + + gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.vert b/src/core/renderers/webgl/filters/FXAA/FXAA.vert new file mode 100755 index 0000000..b0c1860 --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.vert @@ -0,0 +1,45 @@ + +precision mediump float; + +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; + +uniform mat3 projectionMatrix; +uniform vec2 resolution; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + + +void texcoords(vec2 fragCoord, vec2 resolution, + out vec2 v_rgbNW, out vec2 v_rgbNE, + out vec2 v_rgbSW, out vec2 v_rgbSE, + out vec2 v_rgbM) { + vec2 inverseVP = 1.0 / resolution.xy; + v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; + v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; + v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; + v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; + v_rgbM = vec2(fragCoord * inverseVP); +} + +void main(void){ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); + vResolution = resolution; + + //compute the texture coords and send them to varyings + texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js new file mode 100644 index 0000000..6d5646c --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js @@ -0,0 +1,53 @@ +var AbstractFilter = require('./AbstractFilter'); +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * + * Basic FXAA implementation based on the code on geeks3d.com with the + * modification that the texture2DLod stuff was removed since it's + * unsupported by WebGL. + * + * -- + * From: + * https://github.com/mitsuhiko/webgl-meincraft + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * + */ +function FXAAFilter() +{ + AbstractFilter.call(this, + // vertex shader + fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), + // fragment shader + fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), + // uniforms + { + resolution: { type: 'v2', value: { x: 1, y: 1 } } + } + ); + +} + +FXAAFilter.prototype = Object.create(AbstractFilter.prototype); +FXAAFilter.prototype.constructor = FXAAFilter; +module.exports = FXAAFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +FXAAFilter.prototype.applyFilter = function (renderer, input, output) +{ + var filterManager = renderer.filterManager; + + var shader = this.getShader( renderer ); + // draw the filter... + filterManager.applyFilter(shader, input, output); +}; diff --git a/src/core/renderers/webgl/filters/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAAFilter.js deleted file mode 100644 index 6d5646c..0000000 --- a/src/core/renderers/webgl/filters/FXAAFilter.js +++ /dev/null @@ -1,53 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'); -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * - * Basic FXAA implementation based on the code on geeks3d.com with the - * modification that the texture2DLod stuff was removed since it's - * unsupported by WebGL. - * - * -- - * From: - * https://github.com/mitsuhiko/webgl-meincraft - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * - */ -function FXAAFilter() -{ - AbstractFilter.call(this, - // vertex shader - fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), - // fragment shader - fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), - // uniforms - { - resolution: { type: 'v2', value: { x: 1, y: 1 } } - } - ); - -} - -FXAAFilter.prototype = Object.create(AbstractFilter.prototype); -FXAAFilter.prototype.constructor = FXAAFilter; -module.exports = FXAAFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -FXAAFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - var shader = this.getShader( renderer ); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; diff --git a/src/core/renderers/webgl/filters/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/SpriteMaskFilter.js deleted file mode 100644 index ae08ea9..0000000 --- a/src/core/renderers/webgl/filters/SpriteMaskFilter.js +++ /dev/null @@ -1,95 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'), - math = require('../../../math'); - -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * The SpriteMaskFilter class - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * @param sprite {PIXI.Sprite} the target sprite - */ -function SpriteMaskFilter(sprite) -{ - var maskMatrix = new math.Matrix(); - - AbstractFilter.call(this, - fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), - fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8'), - { - mask: { type: 'sampler2D', value: sprite._texture }, - alpha: { type: 'f', value: 1}, - otherMatrix: { type: 'mat3', value: maskMatrix.toArray(true) } - } - ); - - this.maskSprite = sprite; - this.maskMatrix = maskMatrix; -} - -SpriteMaskFilter.prototype = Object.create(AbstractFilter.prototype); -SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; -module.exports = SpriteMaskFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -SpriteMaskFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - this.uniforms.mask.value = this.maskSprite._texture; - - filterManager.calculateMappedMatrix(input.frame, this.maskSprite, this.maskMatrix); - - this.uniforms.otherMatrix.value = this.maskMatrix.toArray(true); - this.uniforms.alpha.value = this.maskSprite.worldAlpha; - - var shader = this.getShader(renderer); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; - - -Object.defineProperties(SpriteMaskFilter.prototype, { - /** - * The texture used for the displacement map. Must be power of 2 sized texture. - * - * @member {PIXI.Texture} - * @memberof PIXI.SpriteMaskFilter# - */ - map: { - get: function () - { - return this.uniforms.mask.value; - }, - set: function (value) - { - this.uniforms.mask.value = value; - } - }, - - /** - * The offset used to move the displacement map. - * - * @member {PIXI.Point} - * @memberof PIXI.SpriteMaskFilter# - */ - offset: { - get: function() - { - return this.uniforms.offset.value; - }, - set: function(value) - { - this.uniforms.offset.value = value; - } - } -}); diff --git a/src/core/renderers/webgl/filters/defaultValue.js b/src/core/renderers/webgl/filters/defaultValue.js deleted file mode 100644 index bcb27f5..0000000 --- a/src/core/renderers/webgl/filters/defaultValue.js +++ /dev/null @@ -1,74 +0,0 @@ - - -var defaultValue = function(type, size) -{ - switch (type) - { - case 'float': - return 0; - - case 'vec2': - return new Float32Array(2 * size); - - case 'vec3': - return new Float32Array(3 * size); - - case 'vec4': - return new Float32Array(4 * size); - - case 'int': - case 'sampler2D': - return 0; - - case 'ivec2': - return new Int32Array(2 * size); - - case 'ivec3': - return new Int32Array(3 * size); - - case 'ivec4': - return new Int32Array(4 * size); - - case 'bool': - return false; - - case 'bvec2': - - return booleanArray( 2 * size); - - case 'bvec3': - return booleanArray(3 * size); - - case 'bvec4': - return booleanArray(4 * size); - - case 'mat2': - return new Float32Array([1, 0 - ,0, 1]); - - case 'mat3': - return new Float32Array([1, 0, 0 - ,0, 1, 0 - ,0, 0, 1]); - - case 'mat4': - return new Float32Array([1, 0, 0, 0 - ,0, 1, 0, 0 - ,0, 0, 1, 0 - ,0, 0, 0, 1]); - } -} - -var booleanArray = function(size) -{ - var array = new Array(size); - - for (var i = 0; i < array.length; i++) - { - array[i] = false; - }; - - return array; -} - -module.exports = defaultValue; diff --git a/src/core/renderers/webgl/filters/shaderParser.js b/src/core/renderers/webgl/filters/shaderParser.js deleted file mode 100644 index 9a94af6..0000000 --- a/src/core/renderers/webgl/filters/shaderParser.js +++ /dev/null @@ -1,109 +0,0 @@ - -/** - * The default vertex shader source - * - * @static - * @constant - */ -var defaultVertexSrc = [ - 'precision lowp float;', - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - - 'uniform mat3 projectionMatrix;', - 'uniform mat3 otherMatrix;', - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vFilterCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy;', - ' vTextureCoord = aTextureCoord ;', - '}' -].join('\n'); - -/** - * The default fragment shader source - * - * @static - * @constant - */ -var defaultFragmentSrc = [ - 'precision lowp float;', - - 'struct Matty{', - ' float some;', - ' float dohave;', - 'float them;', - '};', - - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - 'uniform sampler2D uSampler;', - 'uniform sampler2D filterSampler;', - 'uniform Matty thing;', - - 'void main(void){', - ' vec4 masky = texture2D(filterSampler, vFilterCoord);', - ' vec4 sample = texture2D(uSampler, vTextureCoord);', - ' vec4 color;', - ' if(mod(vFilterCoord.x, 1.0) > 0.5){', - ' ', - ' color = vec4(1.0, 0.0, 0.0, 1.0) + thing.some;', - ' }', - ' else', - ' {', - ' color = vec4(0.0, 1.0, 0.0, 1.0) ;', - ' }', - // ' gl_FragColor = vec4(mod(vFilterCoord.x, 1.5), vFilterCoord.y,0.0,1.0);', - ' gl_FragColor = mix(sample, masky, 0.5);', - ' gl_FragColor *= sample.a;', - '}' -].join('\n'); - -//clean out white space tabs -var lines = defaultFragmentSrc.replace(/\s+/g,' ') - .split(/\s*;\s*/); - -function extractUniforms(vertexSrc, fragmentSrc) -{ - var fragUniforms = extractUniformsFromString(defaultFragmentSrc); - var vertUniforms = extractUniformsFromString(defaultVertexSrc); - - return Object.assign(fragUniforms, vertUniforms); -} - -function mergeObject(object1, object2) -{ - return Object.assign({}, object1, object2); -} - - -function extractUniformsFromString(string) -{ - var uniforms = {}; - - // clean the lines a little - remove extra spaces / teabs etc - // then split along ';' - var lines = string.replace(/\s+/g,' ') - .split(/\s*;\s*/); - - - // loop through.. - for (var i = 0; i < lines.length; i++) - { - var line = lines[i].trim(); - - if(line.indexOf('uniform') > -1) - { - var splitLine = line.split(' '); - var type = splitLine[1]; - var name = splitLine[2]; - console.log(name + " is of type " + type); - uniforms[name] = 0; - } - - return uniforms; - }; -} -//console.log(lines); diff --git a/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js new file mode 100644 index 0000000..f961c94 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js @@ -0,0 +1,50 @@ +var Filter = require('../Filter'), + math = require('../../../../math'); + +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * The SpriteMaskFilter class + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * @param sprite {PIXI.Sprite} the target sprite + */ +function SpriteMaskFilter(sprite) +{ + var maskMatrix = new math.Matrix(); + + Filter.call(this, + fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), + fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8') + ); + + sprite.renderable = false; + + this.maskSprite = sprite; + this.maskMatrix = maskMatrix; +} + +SpriteMaskFilter.prototype = Object.create(Filter.prototype); +SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; +module.exports = SpriteMaskFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +SpriteMaskFilter.prototype.apply = function (filterManager, input, output) +{ + var maskSprite = this.maskSprite; + + this.uniforms.mask = maskSprite._texture; + this.uniforms.otherMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, maskSprite ); + this.uniforms.alpha = maskSprite.worldAlpha; + + filterManager.applyFilter(this, input, output); +}; diff --git a/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag new file mode 100644 index 0000000..690dab0 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag @@ -0,0 +1,20 @@ +precision lowp float; + +varying vec2 vMaskCoord; +varying vec2 vTextureCoord; + +uniform sampler2D uSampler; +uniform float alpha; +uniform sampler2D mask; + +void main(void) +{ + // check clip! this will stop the mask bleeding out from the edges + vec2 text = abs( vMaskCoord - 0.5 ); + text = step(0.5, text); + float clip = 1.0 - max(text.y, text.x); + vec4 original = texture2D(uSampler, vTextureCoord); + vec4 masky = texture2D(mask, vMaskCoord); + original *= (masky.r * masky.a * alpha * clip); + gl_FragColor = original; +} diff --git a/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert new file mode 100644 index 0000000..b864112 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert @@ -0,0 +1,15 @@ +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; + +uniform mat3 projectionMatrix; +uniform mat3 otherMatrix; + +varying vec2 vMaskCoord; +varying vec2 vTextureCoord; + +void main(void) +{ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy; +} diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.frag b/src/core/renderers/webgl/filters/FXAA/FXAA.frag new file mode 100755 index 0000000..2f3b3ae --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.frag @@ -0,0 +1,127 @@ +precision lowp float; + + +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. + +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +varying vec2 vTextureCoord; +varying vec4 vColor; +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + +uniform sampler2D uSampler; + + +void main(void){ + + gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.vert b/src/core/renderers/webgl/filters/FXAA/FXAA.vert new file mode 100755 index 0000000..b0c1860 --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.vert @@ -0,0 +1,45 @@ + +precision mediump float; + +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; + +uniform mat3 projectionMatrix; +uniform vec2 resolution; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + + +void texcoords(vec2 fragCoord, vec2 resolution, + out vec2 v_rgbNW, out vec2 v_rgbNE, + out vec2 v_rgbSW, out vec2 v_rgbSE, + out vec2 v_rgbM) { + vec2 inverseVP = 1.0 / resolution.xy; + v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; + v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; + v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; + v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; + v_rgbM = vec2(fragCoord * inverseVP); +} + +void main(void){ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); + vResolution = resolution; + + //compute the texture coords and send them to varyings + texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js new file mode 100644 index 0000000..6d5646c --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js @@ -0,0 +1,53 @@ +var AbstractFilter = require('./AbstractFilter'); +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * + * Basic FXAA implementation based on the code on geeks3d.com with the + * modification that the texture2DLod stuff was removed since it's + * unsupported by WebGL. + * + * -- + * From: + * https://github.com/mitsuhiko/webgl-meincraft + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * + */ +function FXAAFilter() +{ + AbstractFilter.call(this, + // vertex shader + fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), + // fragment shader + fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), + // uniforms + { + resolution: { type: 'v2', value: { x: 1, y: 1 } } + } + ); + +} + +FXAAFilter.prototype = Object.create(AbstractFilter.prototype); +FXAAFilter.prototype.constructor = FXAAFilter; +module.exports = FXAAFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +FXAAFilter.prototype.applyFilter = function (renderer, input, output) +{ + var filterManager = renderer.filterManager; + + var shader = this.getShader( renderer ); + // draw the filter... + filterManager.applyFilter(shader, input, output); +}; diff --git a/src/core/renderers/webgl/filters/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAAFilter.js deleted file mode 100644 index 6d5646c..0000000 --- a/src/core/renderers/webgl/filters/FXAAFilter.js +++ /dev/null @@ -1,53 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'); -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * - * Basic FXAA implementation based on the code on geeks3d.com with the - * modification that the texture2DLod stuff was removed since it's - * unsupported by WebGL. - * - * -- - * From: - * https://github.com/mitsuhiko/webgl-meincraft - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * - */ -function FXAAFilter() -{ - AbstractFilter.call(this, - // vertex shader - fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), - // fragment shader - fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), - // uniforms - { - resolution: { type: 'v2', value: { x: 1, y: 1 } } - } - ); - -} - -FXAAFilter.prototype = Object.create(AbstractFilter.prototype); -FXAAFilter.prototype.constructor = FXAAFilter; -module.exports = FXAAFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -FXAAFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - var shader = this.getShader( renderer ); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; diff --git a/src/core/renderers/webgl/filters/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/SpriteMaskFilter.js deleted file mode 100644 index ae08ea9..0000000 --- a/src/core/renderers/webgl/filters/SpriteMaskFilter.js +++ /dev/null @@ -1,95 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'), - math = require('../../../math'); - -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * The SpriteMaskFilter class - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * @param sprite {PIXI.Sprite} the target sprite - */ -function SpriteMaskFilter(sprite) -{ - var maskMatrix = new math.Matrix(); - - AbstractFilter.call(this, - fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), - fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8'), - { - mask: { type: 'sampler2D', value: sprite._texture }, - alpha: { type: 'f', value: 1}, - otherMatrix: { type: 'mat3', value: maskMatrix.toArray(true) } - } - ); - - this.maskSprite = sprite; - this.maskMatrix = maskMatrix; -} - -SpriteMaskFilter.prototype = Object.create(AbstractFilter.prototype); -SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; -module.exports = SpriteMaskFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -SpriteMaskFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - this.uniforms.mask.value = this.maskSprite._texture; - - filterManager.calculateMappedMatrix(input.frame, this.maskSprite, this.maskMatrix); - - this.uniforms.otherMatrix.value = this.maskMatrix.toArray(true); - this.uniforms.alpha.value = this.maskSprite.worldAlpha; - - var shader = this.getShader(renderer); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; - - -Object.defineProperties(SpriteMaskFilter.prototype, { - /** - * The texture used for the displacement map. Must be power of 2 sized texture. - * - * @member {PIXI.Texture} - * @memberof PIXI.SpriteMaskFilter# - */ - map: { - get: function () - { - return this.uniforms.mask.value; - }, - set: function (value) - { - this.uniforms.mask.value = value; - } - }, - - /** - * The offset used to move the displacement map. - * - * @member {PIXI.Point} - * @memberof PIXI.SpriteMaskFilter# - */ - offset: { - get: function() - { - return this.uniforms.offset.value; - }, - set: function(value) - { - this.uniforms.offset.value = value; - } - } -}); diff --git a/src/core/renderers/webgl/filters/defaultValue.js b/src/core/renderers/webgl/filters/defaultValue.js deleted file mode 100644 index bcb27f5..0000000 --- a/src/core/renderers/webgl/filters/defaultValue.js +++ /dev/null @@ -1,74 +0,0 @@ - - -var defaultValue = function(type, size) -{ - switch (type) - { - case 'float': - return 0; - - case 'vec2': - return new Float32Array(2 * size); - - case 'vec3': - return new Float32Array(3 * size); - - case 'vec4': - return new Float32Array(4 * size); - - case 'int': - case 'sampler2D': - return 0; - - case 'ivec2': - return new Int32Array(2 * size); - - case 'ivec3': - return new Int32Array(3 * size); - - case 'ivec4': - return new Int32Array(4 * size); - - case 'bool': - return false; - - case 'bvec2': - - return booleanArray( 2 * size); - - case 'bvec3': - return booleanArray(3 * size); - - case 'bvec4': - return booleanArray(4 * size); - - case 'mat2': - return new Float32Array([1, 0 - ,0, 1]); - - case 'mat3': - return new Float32Array([1, 0, 0 - ,0, 1, 0 - ,0, 0, 1]); - - case 'mat4': - return new Float32Array([1, 0, 0, 0 - ,0, 1, 0, 0 - ,0, 0, 1, 0 - ,0, 0, 0, 1]); - } -} - -var booleanArray = function(size) -{ - var array = new Array(size); - - for (var i = 0; i < array.length; i++) - { - array[i] = false; - }; - - return array; -} - -module.exports = defaultValue; diff --git a/src/core/renderers/webgl/filters/shaderParser.js b/src/core/renderers/webgl/filters/shaderParser.js deleted file mode 100644 index 9a94af6..0000000 --- a/src/core/renderers/webgl/filters/shaderParser.js +++ /dev/null @@ -1,109 +0,0 @@ - -/** - * The default vertex shader source - * - * @static - * @constant - */ -var defaultVertexSrc = [ - 'precision lowp float;', - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - - 'uniform mat3 projectionMatrix;', - 'uniform mat3 otherMatrix;', - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vFilterCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy;', - ' vTextureCoord = aTextureCoord ;', - '}' -].join('\n'); - -/** - * The default fragment shader source - * - * @static - * @constant - */ -var defaultFragmentSrc = [ - 'precision lowp float;', - - 'struct Matty{', - ' float some;', - ' float dohave;', - 'float them;', - '};', - - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - 'uniform sampler2D uSampler;', - 'uniform sampler2D filterSampler;', - 'uniform Matty thing;', - - 'void main(void){', - ' vec4 masky = texture2D(filterSampler, vFilterCoord);', - ' vec4 sample = texture2D(uSampler, vTextureCoord);', - ' vec4 color;', - ' if(mod(vFilterCoord.x, 1.0) > 0.5){', - ' ', - ' color = vec4(1.0, 0.0, 0.0, 1.0) + thing.some;', - ' }', - ' else', - ' {', - ' color = vec4(0.0, 1.0, 0.0, 1.0) ;', - ' }', - // ' gl_FragColor = vec4(mod(vFilterCoord.x, 1.5), vFilterCoord.y,0.0,1.0);', - ' gl_FragColor = mix(sample, masky, 0.5);', - ' gl_FragColor *= sample.a;', - '}' -].join('\n'); - -//clean out white space tabs -var lines = defaultFragmentSrc.replace(/\s+/g,' ') - .split(/\s*;\s*/); - -function extractUniforms(vertexSrc, fragmentSrc) -{ - var fragUniforms = extractUniformsFromString(defaultFragmentSrc); - var vertUniforms = extractUniformsFromString(defaultVertexSrc); - - return Object.assign(fragUniforms, vertUniforms); -} - -function mergeObject(object1, object2) -{ - return Object.assign({}, object1, object2); -} - - -function extractUniformsFromString(string) -{ - var uniforms = {}; - - // clean the lines a little - remove extra spaces / teabs etc - // then split along ';' - var lines = string.replace(/\s+/g,' ') - .split(/\s*;\s*/); - - - // loop through.. - for (var i = 0; i < lines.length; i++) - { - var line = lines[i].trim(); - - if(line.indexOf('uniform') > -1) - { - var splitLine = line.split(' '); - var type = splitLine[1]; - var name = splitLine[2]; - console.log(name + " is of type " + type); - uniforms[name] = 0; - } - - return uniforms; - }; -} -//console.log(lines); diff --git a/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js new file mode 100644 index 0000000..f961c94 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js @@ -0,0 +1,50 @@ +var Filter = require('../Filter'), + math = require('../../../../math'); + +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * The SpriteMaskFilter class + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * @param sprite {PIXI.Sprite} the target sprite + */ +function SpriteMaskFilter(sprite) +{ + var maskMatrix = new math.Matrix(); + + Filter.call(this, + fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), + fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8') + ); + + sprite.renderable = false; + + this.maskSprite = sprite; + this.maskMatrix = maskMatrix; +} + +SpriteMaskFilter.prototype = Object.create(Filter.prototype); +SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; +module.exports = SpriteMaskFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +SpriteMaskFilter.prototype.apply = function (filterManager, input, output) +{ + var maskSprite = this.maskSprite; + + this.uniforms.mask = maskSprite._texture; + this.uniforms.otherMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, maskSprite ); + this.uniforms.alpha = maskSprite.worldAlpha; + + filterManager.applyFilter(this, input, output); +}; diff --git a/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag new file mode 100644 index 0000000..690dab0 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag @@ -0,0 +1,20 @@ +precision lowp float; + +varying vec2 vMaskCoord; +varying vec2 vTextureCoord; + +uniform sampler2D uSampler; +uniform float alpha; +uniform sampler2D mask; + +void main(void) +{ + // check clip! this will stop the mask bleeding out from the edges + vec2 text = abs( vMaskCoord - 0.5 ); + text = step(0.5, text); + float clip = 1.0 - max(text.y, text.x); + vec4 original = texture2D(uSampler, vTextureCoord); + vec4 masky = texture2D(mask, vMaskCoord); + original *= (masky.r * masky.a * alpha * clip); + gl_FragColor = original; +} diff --git a/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert new file mode 100644 index 0000000..b864112 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert @@ -0,0 +1,15 @@ +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; + +uniform mat3 projectionMatrix; +uniform mat3 otherMatrix; + +varying vec2 vMaskCoord; +varying vec2 vTextureCoord; + +void main(void) +{ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy; +} diff --git a/src/core/renderers/webgl/filters/spriteMaskFilter.frag b/src/core/renderers/webgl/filters/spriteMaskFilter.frag deleted file mode 100644 index ff8880c..0000000 --- a/src/core/renderers/webgl/filters/spriteMaskFilter.frag +++ /dev/null @@ -1,21 +0,0 @@ -precision lowp float; - -varying vec2 vMaskCoord; -varying vec2 vTextureCoord; -varying vec4 vColor; - -uniform sampler2D uSampler; -uniform float alpha; -uniform sampler2D mask; - -void main(void) -{ - // check clip! this will stop the mask bleeding out from the edges - vec2 text = abs( vMaskCoord - 0.5 ); - text = step(0.5, text); - float clip = 1.0 - max(text.y, text.x); - vec4 original = texture2D(uSampler, vTextureCoord); - vec4 masky = texture2D(mask, vMaskCoord); - original *= (masky.r * masky.a * alpha * clip); - gl_FragColor = original; -} diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.frag b/src/core/renderers/webgl/filters/FXAA/FXAA.frag new file mode 100755 index 0000000..2f3b3ae --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.frag @@ -0,0 +1,127 @@ +precision lowp float; + + +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. + +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +varying vec2 vTextureCoord; +varying vec4 vColor; +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + +uniform sampler2D uSampler; + + +void main(void){ + + gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.vert b/src/core/renderers/webgl/filters/FXAA/FXAA.vert new file mode 100755 index 0000000..b0c1860 --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.vert @@ -0,0 +1,45 @@ + +precision mediump float; + +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; + +uniform mat3 projectionMatrix; +uniform vec2 resolution; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + + +void texcoords(vec2 fragCoord, vec2 resolution, + out vec2 v_rgbNW, out vec2 v_rgbNE, + out vec2 v_rgbSW, out vec2 v_rgbSE, + out vec2 v_rgbM) { + vec2 inverseVP = 1.0 / resolution.xy; + v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; + v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; + v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; + v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; + v_rgbM = vec2(fragCoord * inverseVP); +} + +void main(void){ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); + vResolution = resolution; + + //compute the texture coords and send them to varyings + texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js new file mode 100644 index 0000000..6d5646c --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js @@ -0,0 +1,53 @@ +var AbstractFilter = require('./AbstractFilter'); +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * + * Basic FXAA implementation based on the code on geeks3d.com with the + * modification that the texture2DLod stuff was removed since it's + * unsupported by WebGL. + * + * -- + * From: + * https://github.com/mitsuhiko/webgl-meincraft + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * + */ +function FXAAFilter() +{ + AbstractFilter.call(this, + // vertex shader + fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), + // fragment shader + fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), + // uniforms + { + resolution: { type: 'v2', value: { x: 1, y: 1 } } + } + ); + +} + +FXAAFilter.prototype = Object.create(AbstractFilter.prototype); +FXAAFilter.prototype.constructor = FXAAFilter; +module.exports = FXAAFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +FXAAFilter.prototype.applyFilter = function (renderer, input, output) +{ + var filterManager = renderer.filterManager; + + var shader = this.getShader( renderer ); + // draw the filter... + filterManager.applyFilter(shader, input, output); +}; diff --git a/src/core/renderers/webgl/filters/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAAFilter.js deleted file mode 100644 index 6d5646c..0000000 --- a/src/core/renderers/webgl/filters/FXAAFilter.js +++ /dev/null @@ -1,53 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'); -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * - * Basic FXAA implementation based on the code on geeks3d.com with the - * modification that the texture2DLod stuff was removed since it's - * unsupported by WebGL. - * - * -- - * From: - * https://github.com/mitsuhiko/webgl-meincraft - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * - */ -function FXAAFilter() -{ - AbstractFilter.call(this, - // vertex shader - fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), - // fragment shader - fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), - // uniforms - { - resolution: { type: 'v2', value: { x: 1, y: 1 } } - } - ); - -} - -FXAAFilter.prototype = Object.create(AbstractFilter.prototype); -FXAAFilter.prototype.constructor = FXAAFilter; -module.exports = FXAAFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -FXAAFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - var shader = this.getShader( renderer ); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; diff --git a/src/core/renderers/webgl/filters/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/SpriteMaskFilter.js deleted file mode 100644 index ae08ea9..0000000 --- a/src/core/renderers/webgl/filters/SpriteMaskFilter.js +++ /dev/null @@ -1,95 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'), - math = require('../../../math'); - -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * The SpriteMaskFilter class - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * @param sprite {PIXI.Sprite} the target sprite - */ -function SpriteMaskFilter(sprite) -{ - var maskMatrix = new math.Matrix(); - - AbstractFilter.call(this, - fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), - fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8'), - { - mask: { type: 'sampler2D', value: sprite._texture }, - alpha: { type: 'f', value: 1}, - otherMatrix: { type: 'mat3', value: maskMatrix.toArray(true) } - } - ); - - this.maskSprite = sprite; - this.maskMatrix = maskMatrix; -} - -SpriteMaskFilter.prototype = Object.create(AbstractFilter.prototype); -SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; -module.exports = SpriteMaskFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -SpriteMaskFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - this.uniforms.mask.value = this.maskSprite._texture; - - filterManager.calculateMappedMatrix(input.frame, this.maskSprite, this.maskMatrix); - - this.uniforms.otherMatrix.value = this.maskMatrix.toArray(true); - this.uniforms.alpha.value = this.maskSprite.worldAlpha; - - var shader = this.getShader(renderer); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; - - -Object.defineProperties(SpriteMaskFilter.prototype, { - /** - * The texture used for the displacement map. Must be power of 2 sized texture. - * - * @member {PIXI.Texture} - * @memberof PIXI.SpriteMaskFilter# - */ - map: { - get: function () - { - return this.uniforms.mask.value; - }, - set: function (value) - { - this.uniforms.mask.value = value; - } - }, - - /** - * The offset used to move the displacement map. - * - * @member {PIXI.Point} - * @memberof PIXI.SpriteMaskFilter# - */ - offset: { - get: function() - { - return this.uniforms.offset.value; - }, - set: function(value) - { - this.uniforms.offset.value = value; - } - } -}); diff --git a/src/core/renderers/webgl/filters/defaultValue.js b/src/core/renderers/webgl/filters/defaultValue.js deleted file mode 100644 index bcb27f5..0000000 --- a/src/core/renderers/webgl/filters/defaultValue.js +++ /dev/null @@ -1,74 +0,0 @@ - - -var defaultValue = function(type, size) -{ - switch (type) - { - case 'float': - return 0; - - case 'vec2': - return new Float32Array(2 * size); - - case 'vec3': - return new Float32Array(3 * size); - - case 'vec4': - return new Float32Array(4 * size); - - case 'int': - case 'sampler2D': - return 0; - - case 'ivec2': - return new Int32Array(2 * size); - - case 'ivec3': - return new Int32Array(3 * size); - - case 'ivec4': - return new Int32Array(4 * size); - - case 'bool': - return false; - - case 'bvec2': - - return booleanArray( 2 * size); - - case 'bvec3': - return booleanArray(3 * size); - - case 'bvec4': - return booleanArray(4 * size); - - case 'mat2': - return new Float32Array([1, 0 - ,0, 1]); - - case 'mat3': - return new Float32Array([1, 0, 0 - ,0, 1, 0 - ,0, 0, 1]); - - case 'mat4': - return new Float32Array([1, 0, 0, 0 - ,0, 1, 0, 0 - ,0, 0, 1, 0 - ,0, 0, 0, 1]); - } -} - -var booleanArray = function(size) -{ - var array = new Array(size); - - for (var i = 0; i < array.length; i++) - { - array[i] = false; - }; - - return array; -} - -module.exports = defaultValue; diff --git a/src/core/renderers/webgl/filters/shaderParser.js b/src/core/renderers/webgl/filters/shaderParser.js deleted file mode 100644 index 9a94af6..0000000 --- a/src/core/renderers/webgl/filters/shaderParser.js +++ /dev/null @@ -1,109 +0,0 @@ - -/** - * The default vertex shader source - * - * @static - * @constant - */ -var defaultVertexSrc = [ - 'precision lowp float;', - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - - 'uniform mat3 projectionMatrix;', - 'uniform mat3 otherMatrix;', - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vFilterCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy;', - ' vTextureCoord = aTextureCoord ;', - '}' -].join('\n'); - -/** - * The default fragment shader source - * - * @static - * @constant - */ -var defaultFragmentSrc = [ - 'precision lowp float;', - - 'struct Matty{', - ' float some;', - ' float dohave;', - 'float them;', - '};', - - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - 'uniform sampler2D uSampler;', - 'uniform sampler2D filterSampler;', - 'uniform Matty thing;', - - 'void main(void){', - ' vec4 masky = texture2D(filterSampler, vFilterCoord);', - ' vec4 sample = texture2D(uSampler, vTextureCoord);', - ' vec4 color;', - ' if(mod(vFilterCoord.x, 1.0) > 0.5){', - ' ', - ' color = vec4(1.0, 0.0, 0.0, 1.0) + thing.some;', - ' }', - ' else', - ' {', - ' color = vec4(0.0, 1.0, 0.0, 1.0) ;', - ' }', - // ' gl_FragColor = vec4(mod(vFilterCoord.x, 1.5), vFilterCoord.y,0.0,1.0);', - ' gl_FragColor = mix(sample, masky, 0.5);', - ' gl_FragColor *= sample.a;', - '}' -].join('\n'); - -//clean out white space tabs -var lines = defaultFragmentSrc.replace(/\s+/g,' ') - .split(/\s*;\s*/); - -function extractUniforms(vertexSrc, fragmentSrc) -{ - var fragUniforms = extractUniformsFromString(defaultFragmentSrc); - var vertUniforms = extractUniformsFromString(defaultVertexSrc); - - return Object.assign(fragUniforms, vertUniforms); -} - -function mergeObject(object1, object2) -{ - return Object.assign({}, object1, object2); -} - - -function extractUniformsFromString(string) -{ - var uniforms = {}; - - // clean the lines a little - remove extra spaces / teabs etc - // then split along ';' - var lines = string.replace(/\s+/g,' ') - .split(/\s*;\s*/); - - - // loop through.. - for (var i = 0; i < lines.length; i++) - { - var line = lines[i].trim(); - - if(line.indexOf('uniform') > -1) - { - var splitLine = line.split(' '); - var type = splitLine[1]; - var name = splitLine[2]; - console.log(name + " is of type " + type); - uniforms[name] = 0; - } - - return uniforms; - }; -} -//console.log(lines); diff --git a/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js new file mode 100644 index 0000000..f961c94 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js @@ -0,0 +1,50 @@ +var Filter = require('../Filter'), + math = require('../../../../math'); + +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * The SpriteMaskFilter class + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * @param sprite {PIXI.Sprite} the target sprite + */ +function SpriteMaskFilter(sprite) +{ + var maskMatrix = new math.Matrix(); + + Filter.call(this, + fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), + fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8') + ); + + sprite.renderable = false; + + this.maskSprite = sprite; + this.maskMatrix = maskMatrix; +} + +SpriteMaskFilter.prototype = Object.create(Filter.prototype); +SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; +module.exports = SpriteMaskFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +SpriteMaskFilter.prototype.apply = function (filterManager, input, output) +{ + var maskSprite = this.maskSprite; + + this.uniforms.mask = maskSprite._texture; + this.uniforms.otherMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, maskSprite ); + this.uniforms.alpha = maskSprite.worldAlpha; + + filterManager.applyFilter(this, input, output); +}; diff --git a/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag new file mode 100644 index 0000000..690dab0 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag @@ -0,0 +1,20 @@ +precision lowp float; + +varying vec2 vMaskCoord; +varying vec2 vTextureCoord; + +uniform sampler2D uSampler; +uniform float alpha; +uniform sampler2D mask; + +void main(void) +{ + // check clip! this will stop the mask bleeding out from the edges + vec2 text = abs( vMaskCoord - 0.5 ); + text = step(0.5, text); + float clip = 1.0 - max(text.y, text.x); + vec4 original = texture2D(uSampler, vTextureCoord); + vec4 masky = texture2D(mask, vMaskCoord); + original *= (masky.r * masky.a * alpha * clip); + gl_FragColor = original; +} diff --git a/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert new file mode 100644 index 0000000..b864112 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert @@ -0,0 +1,15 @@ +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; + +uniform mat3 projectionMatrix; +uniform mat3 otherMatrix; + +varying vec2 vMaskCoord; +varying vec2 vTextureCoord; + +void main(void) +{ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy; +} diff --git a/src/core/renderers/webgl/filters/spriteMaskFilter.frag b/src/core/renderers/webgl/filters/spriteMaskFilter.frag deleted file mode 100644 index ff8880c..0000000 --- a/src/core/renderers/webgl/filters/spriteMaskFilter.frag +++ /dev/null @@ -1,21 +0,0 @@ -precision lowp float; - -varying vec2 vMaskCoord; -varying vec2 vTextureCoord; -varying vec4 vColor; - -uniform sampler2D uSampler; -uniform float alpha; -uniform sampler2D mask; - -void main(void) -{ - // check clip! this will stop the mask bleeding out from the edges - vec2 text = abs( vMaskCoord - 0.5 ); - text = step(0.5, text); - float clip = 1.0 - max(text.y, text.x); - vec4 original = texture2D(uSampler, vTextureCoord); - vec4 masky = texture2D(mask, vMaskCoord); - original *= (masky.r * masky.a * alpha * clip); - gl_FragColor = original; -} diff --git a/src/core/renderers/webgl/filters/spriteMaskFilter.vert b/src/core/renderers/webgl/filters/spriteMaskFilter.vert deleted file mode 100644 index 5299c1f..0000000 --- a/src/core/renderers/webgl/filters/spriteMaskFilter.vert +++ /dev/null @@ -1,18 +0,0 @@ -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform mat3 otherMatrix; - -varying vec2 vMaskCoord; -varying vec2 vTextureCoord; -varying vec4 vColor; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); -} diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.frag b/src/core/renderers/webgl/filters/FXAA/FXAA.frag new file mode 100755 index 0000000..2f3b3ae --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.frag @@ -0,0 +1,127 @@ +precision lowp float; + + +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. + +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +varying vec2 vTextureCoord; +varying vec4 vColor; +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + +uniform sampler2D uSampler; + + +void main(void){ + + gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.vert b/src/core/renderers/webgl/filters/FXAA/FXAA.vert new file mode 100755 index 0000000..b0c1860 --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.vert @@ -0,0 +1,45 @@ + +precision mediump float; + +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; + +uniform mat3 projectionMatrix; +uniform vec2 resolution; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + + +void texcoords(vec2 fragCoord, vec2 resolution, + out vec2 v_rgbNW, out vec2 v_rgbNE, + out vec2 v_rgbSW, out vec2 v_rgbSE, + out vec2 v_rgbM) { + vec2 inverseVP = 1.0 / resolution.xy; + v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; + v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; + v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; + v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; + v_rgbM = vec2(fragCoord * inverseVP); +} + +void main(void){ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); + vResolution = resolution; + + //compute the texture coords and send them to varyings + texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js new file mode 100644 index 0000000..6d5646c --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js @@ -0,0 +1,53 @@ +var AbstractFilter = require('./AbstractFilter'); +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * + * Basic FXAA implementation based on the code on geeks3d.com with the + * modification that the texture2DLod stuff was removed since it's + * unsupported by WebGL. + * + * -- + * From: + * https://github.com/mitsuhiko/webgl-meincraft + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * + */ +function FXAAFilter() +{ + AbstractFilter.call(this, + // vertex shader + fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), + // fragment shader + fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), + // uniforms + { + resolution: { type: 'v2', value: { x: 1, y: 1 } } + } + ); + +} + +FXAAFilter.prototype = Object.create(AbstractFilter.prototype); +FXAAFilter.prototype.constructor = FXAAFilter; +module.exports = FXAAFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +FXAAFilter.prototype.applyFilter = function (renderer, input, output) +{ + var filterManager = renderer.filterManager; + + var shader = this.getShader( renderer ); + // draw the filter... + filterManager.applyFilter(shader, input, output); +}; diff --git a/src/core/renderers/webgl/filters/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAAFilter.js deleted file mode 100644 index 6d5646c..0000000 --- a/src/core/renderers/webgl/filters/FXAAFilter.js +++ /dev/null @@ -1,53 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'); -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * - * Basic FXAA implementation based on the code on geeks3d.com with the - * modification that the texture2DLod stuff was removed since it's - * unsupported by WebGL. - * - * -- - * From: - * https://github.com/mitsuhiko/webgl-meincraft - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * - */ -function FXAAFilter() -{ - AbstractFilter.call(this, - // vertex shader - fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), - // fragment shader - fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), - // uniforms - { - resolution: { type: 'v2', value: { x: 1, y: 1 } } - } - ); - -} - -FXAAFilter.prototype = Object.create(AbstractFilter.prototype); -FXAAFilter.prototype.constructor = FXAAFilter; -module.exports = FXAAFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -FXAAFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - var shader = this.getShader( renderer ); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; diff --git a/src/core/renderers/webgl/filters/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/SpriteMaskFilter.js deleted file mode 100644 index ae08ea9..0000000 --- a/src/core/renderers/webgl/filters/SpriteMaskFilter.js +++ /dev/null @@ -1,95 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'), - math = require('../../../math'); - -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * The SpriteMaskFilter class - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * @param sprite {PIXI.Sprite} the target sprite - */ -function SpriteMaskFilter(sprite) -{ - var maskMatrix = new math.Matrix(); - - AbstractFilter.call(this, - fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), - fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8'), - { - mask: { type: 'sampler2D', value: sprite._texture }, - alpha: { type: 'f', value: 1}, - otherMatrix: { type: 'mat3', value: maskMatrix.toArray(true) } - } - ); - - this.maskSprite = sprite; - this.maskMatrix = maskMatrix; -} - -SpriteMaskFilter.prototype = Object.create(AbstractFilter.prototype); -SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; -module.exports = SpriteMaskFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -SpriteMaskFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - this.uniforms.mask.value = this.maskSprite._texture; - - filterManager.calculateMappedMatrix(input.frame, this.maskSprite, this.maskMatrix); - - this.uniforms.otherMatrix.value = this.maskMatrix.toArray(true); - this.uniforms.alpha.value = this.maskSprite.worldAlpha; - - var shader = this.getShader(renderer); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; - - -Object.defineProperties(SpriteMaskFilter.prototype, { - /** - * The texture used for the displacement map. Must be power of 2 sized texture. - * - * @member {PIXI.Texture} - * @memberof PIXI.SpriteMaskFilter# - */ - map: { - get: function () - { - return this.uniforms.mask.value; - }, - set: function (value) - { - this.uniforms.mask.value = value; - } - }, - - /** - * The offset used to move the displacement map. - * - * @member {PIXI.Point} - * @memberof PIXI.SpriteMaskFilter# - */ - offset: { - get: function() - { - return this.uniforms.offset.value; - }, - set: function(value) - { - this.uniforms.offset.value = value; - } - } -}); diff --git a/src/core/renderers/webgl/filters/defaultValue.js b/src/core/renderers/webgl/filters/defaultValue.js deleted file mode 100644 index bcb27f5..0000000 --- a/src/core/renderers/webgl/filters/defaultValue.js +++ /dev/null @@ -1,74 +0,0 @@ - - -var defaultValue = function(type, size) -{ - switch (type) - { - case 'float': - return 0; - - case 'vec2': - return new Float32Array(2 * size); - - case 'vec3': - return new Float32Array(3 * size); - - case 'vec4': - return new Float32Array(4 * size); - - case 'int': - case 'sampler2D': - return 0; - - case 'ivec2': - return new Int32Array(2 * size); - - case 'ivec3': - return new Int32Array(3 * size); - - case 'ivec4': - return new Int32Array(4 * size); - - case 'bool': - return false; - - case 'bvec2': - - return booleanArray( 2 * size); - - case 'bvec3': - return booleanArray(3 * size); - - case 'bvec4': - return booleanArray(4 * size); - - case 'mat2': - return new Float32Array([1, 0 - ,0, 1]); - - case 'mat3': - return new Float32Array([1, 0, 0 - ,0, 1, 0 - ,0, 0, 1]); - - case 'mat4': - return new Float32Array([1, 0, 0, 0 - ,0, 1, 0, 0 - ,0, 0, 1, 0 - ,0, 0, 0, 1]); - } -} - -var booleanArray = function(size) -{ - var array = new Array(size); - - for (var i = 0; i < array.length; i++) - { - array[i] = false; - }; - - return array; -} - -module.exports = defaultValue; diff --git a/src/core/renderers/webgl/filters/shaderParser.js b/src/core/renderers/webgl/filters/shaderParser.js deleted file mode 100644 index 9a94af6..0000000 --- a/src/core/renderers/webgl/filters/shaderParser.js +++ /dev/null @@ -1,109 +0,0 @@ - -/** - * The default vertex shader source - * - * @static - * @constant - */ -var defaultVertexSrc = [ - 'precision lowp float;', - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - - 'uniform mat3 projectionMatrix;', - 'uniform mat3 otherMatrix;', - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vFilterCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy;', - ' vTextureCoord = aTextureCoord ;', - '}' -].join('\n'); - -/** - * The default fragment shader source - * - * @static - * @constant - */ -var defaultFragmentSrc = [ - 'precision lowp float;', - - 'struct Matty{', - ' float some;', - ' float dohave;', - 'float them;', - '};', - - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - 'uniform sampler2D uSampler;', - 'uniform sampler2D filterSampler;', - 'uniform Matty thing;', - - 'void main(void){', - ' vec4 masky = texture2D(filterSampler, vFilterCoord);', - ' vec4 sample = texture2D(uSampler, vTextureCoord);', - ' vec4 color;', - ' if(mod(vFilterCoord.x, 1.0) > 0.5){', - ' ', - ' color = vec4(1.0, 0.0, 0.0, 1.0) + thing.some;', - ' }', - ' else', - ' {', - ' color = vec4(0.0, 1.0, 0.0, 1.0) ;', - ' }', - // ' gl_FragColor = vec4(mod(vFilterCoord.x, 1.5), vFilterCoord.y,0.0,1.0);', - ' gl_FragColor = mix(sample, masky, 0.5);', - ' gl_FragColor *= sample.a;', - '}' -].join('\n'); - -//clean out white space tabs -var lines = defaultFragmentSrc.replace(/\s+/g,' ') - .split(/\s*;\s*/); - -function extractUniforms(vertexSrc, fragmentSrc) -{ - var fragUniforms = extractUniformsFromString(defaultFragmentSrc); - var vertUniforms = extractUniformsFromString(defaultVertexSrc); - - return Object.assign(fragUniforms, vertUniforms); -} - -function mergeObject(object1, object2) -{ - return Object.assign({}, object1, object2); -} - - -function extractUniformsFromString(string) -{ - var uniforms = {}; - - // clean the lines a little - remove extra spaces / teabs etc - // then split along ';' - var lines = string.replace(/\s+/g,' ') - .split(/\s*;\s*/); - - - // loop through.. - for (var i = 0; i < lines.length; i++) - { - var line = lines[i].trim(); - - if(line.indexOf('uniform') > -1) - { - var splitLine = line.split(' '); - var type = splitLine[1]; - var name = splitLine[2]; - console.log(name + " is of type " + type); - uniforms[name] = 0; - } - - return uniforms; - }; -} -//console.log(lines); diff --git a/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js new file mode 100644 index 0000000..f961c94 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js @@ -0,0 +1,50 @@ +var Filter = require('../Filter'), + math = require('../../../../math'); + +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * The SpriteMaskFilter class + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * @param sprite {PIXI.Sprite} the target sprite + */ +function SpriteMaskFilter(sprite) +{ + var maskMatrix = new math.Matrix(); + + Filter.call(this, + fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), + fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8') + ); + + sprite.renderable = false; + + this.maskSprite = sprite; + this.maskMatrix = maskMatrix; +} + +SpriteMaskFilter.prototype = Object.create(Filter.prototype); +SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; +module.exports = SpriteMaskFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +SpriteMaskFilter.prototype.apply = function (filterManager, input, output) +{ + var maskSprite = this.maskSprite; + + this.uniforms.mask = maskSprite._texture; + this.uniforms.otherMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, maskSprite ); + this.uniforms.alpha = maskSprite.worldAlpha; + + filterManager.applyFilter(this, input, output); +}; diff --git a/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag new file mode 100644 index 0000000..690dab0 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag @@ -0,0 +1,20 @@ +precision lowp float; + +varying vec2 vMaskCoord; +varying vec2 vTextureCoord; + +uniform sampler2D uSampler; +uniform float alpha; +uniform sampler2D mask; + +void main(void) +{ + // check clip! this will stop the mask bleeding out from the edges + vec2 text = abs( vMaskCoord - 0.5 ); + text = step(0.5, text); + float clip = 1.0 - max(text.y, text.x); + vec4 original = texture2D(uSampler, vTextureCoord); + vec4 masky = texture2D(mask, vMaskCoord); + original *= (masky.r * masky.a * alpha * clip); + gl_FragColor = original; +} diff --git a/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert new file mode 100644 index 0000000..b864112 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert @@ -0,0 +1,15 @@ +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; + +uniform mat3 projectionMatrix; +uniform mat3 otherMatrix; + +varying vec2 vMaskCoord; +varying vec2 vTextureCoord; + +void main(void) +{ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy; +} diff --git a/src/core/renderers/webgl/filters/spriteMaskFilter.frag b/src/core/renderers/webgl/filters/spriteMaskFilter.frag deleted file mode 100644 index ff8880c..0000000 --- a/src/core/renderers/webgl/filters/spriteMaskFilter.frag +++ /dev/null @@ -1,21 +0,0 @@ -precision lowp float; - -varying vec2 vMaskCoord; -varying vec2 vTextureCoord; -varying vec4 vColor; - -uniform sampler2D uSampler; -uniform float alpha; -uniform sampler2D mask; - -void main(void) -{ - // check clip! this will stop the mask bleeding out from the edges - vec2 text = abs( vMaskCoord - 0.5 ); - text = step(0.5, text); - float clip = 1.0 - max(text.y, text.x); - vec4 original = texture2D(uSampler, vTextureCoord); - vec4 masky = texture2D(mask, vMaskCoord); - original *= (masky.r * masky.a * alpha * clip); - gl_FragColor = original; -} diff --git a/src/core/renderers/webgl/filters/spriteMaskFilter.vert b/src/core/renderers/webgl/filters/spriteMaskFilter.vert deleted file mode 100644 index 5299c1f..0000000 --- a/src/core/renderers/webgl/filters/spriteMaskFilter.vert +++ /dev/null @@ -1,18 +0,0 @@ -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform mat3 otherMatrix; - -varying vec2 vMaskCoord; -varying vec2 vTextureCoord; -varying vec4 vColor; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); -} diff --git a/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js b/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js index 4d0221a..7d460f4 100644 --- a/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js +++ b/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js @@ -2,7 +2,6 @@ RenderTarget = require('../utils/RenderTarget'), CONST = require('../../../const'), Quad = require('../utils/Quad'), - FilterShader = require('../filters/FilterShader'), math = require('../../../math'), utils = require('../../../utils'), Shader = require('pixi-gl-core').GLShader, @@ -21,10 +20,8 @@ { WebGLManager.call(this, renderer); - // TODO - not really required. but useful for setting the quad.. - this.filterShader = new FilterShader(renderer.gl); // know about sprites! - this.quad = new Quad(gl, this.filterShader); + this.quad = new Quad(gl); this.stack = [{ target:null, @@ -90,7 +87,7 @@ { var gl = this.renderer.gl; - + var lastState = this.stack[this.stackIndex-1]; var currentState = this.stack[this.stackIndex]; this.quad.map(currentState.renderTarget.size, currentState.sourceFrame).upload(); @@ -98,7 +95,6 @@ var filter = currentState.filters[0]; // lets get the last state as that contains the renderTarget we need to render too - var lastState = this.stack[this.stackIndex-1]; filter.apply(this, currentState.renderTarget, lastState.renderTarget, false); // return the texture.. diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.frag b/src/core/renderers/webgl/filters/FXAA/FXAA.frag new file mode 100755 index 0000000..2f3b3ae --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.frag @@ -0,0 +1,127 @@ +precision lowp float; + + +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. + +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +varying vec2 vTextureCoord; +varying vec4 vColor; +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + +uniform sampler2D uSampler; + + +void main(void){ + + gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.vert b/src/core/renderers/webgl/filters/FXAA/FXAA.vert new file mode 100755 index 0000000..b0c1860 --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.vert @@ -0,0 +1,45 @@ + +precision mediump float; + +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; + +uniform mat3 projectionMatrix; +uniform vec2 resolution; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + + +void texcoords(vec2 fragCoord, vec2 resolution, + out vec2 v_rgbNW, out vec2 v_rgbNE, + out vec2 v_rgbSW, out vec2 v_rgbSE, + out vec2 v_rgbM) { + vec2 inverseVP = 1.0 / resolution.xy; + v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; + v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; + v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; + v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; + v_rgbM = vec2(fragCoord * inverseVP); +} + +void main(void){ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); + vResolution = resolution; + + //compute the texture coords and send them to varyings + texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js new file mode 100644 index 0000000..6d5646c --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js @@ -0,0 +1,53 @@ +var AbstractFilter = require('./AbstractFilter'); +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * + * Basic FXAA implementation based on the code on geeks3d.com with the + * modification that the texture2DLod stuff was removed since it's + * unsupported by WebGL. + * + * -- + * From: + * https://github.com/mitsuhiko/webgl-meincraft + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * + */ +function FXAAFilter() +{ + AbstractFilter.call(this, + // vertex shader + fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), + // fragment shader + fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), + // uniforms + { + resolution: { type: 'v2', value: { x: 1, y: 1 } } + } + ); + +} + +FXAAFilter.prototype = Object.create(AbstractFilter.prototype); +FXAAFilter.prototype.constructor = FXAAFilter; +module.exports = FXAAFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +FXAAFilter.prototype.applyFilter = function (renderer, input, output) +{ + var filterManager = renderer.filterManager; + + var shader = this.getShader( renderer ); + // draw the filter... + filterManager.applyFilter(shader, input, output); +}; diff --git a/src/core/renderers/webgl/filters/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAAFilter.js deleted file mode 100644 index 6d5646c..0000000 --- a/src/core/renderers/webgl/filters/FXAAFilter.js +++ /dev/null @@ -1,53 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'); -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * - * Basic FXAA implementation based on the code on geeks3d.com with the - * modification that the texture2DLod stuff was removed since it's - * unsupported by WebGL. - * - * -- - * From: - * https://github.com/mitsuhiko/webgl-meincraft - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * - */ -function FXAAFilter() -{ - AbstractFilter.call(this, - // vertex shader - fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), - // fragment shader - fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), - // uniforms - { - resolution: { type: 'v2', value: { x: 1, y: 1 } } - } - ); - -} - -FXAAFilter.prototype = Object.create(AbstractFilter.prototype); -FXAAFilter.prototype.constructor = FXAAFilter; -module.exports = FXAAFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -FXAAFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - var shader = this.getShader( renderer ); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; diff --git a/src/core/renderers/webgl/filters/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/SpriteMaskFilter.js deleted file mode 100644 index ae08ea9..0000000 --- a/src/core/renderers/webgl/filters/SpriteMaskFilter.js +++ /dev/null @@ -1,95 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'), - math = require('../../../math'); - -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * The SpriteMaskFilter class - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * @param sprite {PIXI.Sprite} the target sprite - */ -function SpriteMaskFilter(sprite) -{ - var maskMatrix = new math.Matrix(); - - AbstractFilter.call(this, - fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), - fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8'), - { - mask: { type: 'sampler2D', value: sprite._texture }, - alpha: { type: 'f', value: 1}, - otherMatrix: { type: 'mat3', value: maskMatrix.toArray(true) } - } - ); - - this.maskSprite = sprite; - this.maskMatrix = maskMatrix; -} - -SpriteMaskFilter.prototype = Object.create(AbstractFilter.prototype); -SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; -module.exports = SpriteMaskFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -SpriteMaskFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - this.uniforms.mask.value = this.maskSprite._texture; - - filterManager.calculateMappedMatrix(input.frame, this.maskSprite, this.maskMatrix); - - this.uniforms.otherMatrix.value = this.maskMatrix.toArray(true); - this.uniforms.alpha.value = this.maskSprite.worldAlpha; - - var shader = this.getShader(renderer); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; - - -Object.defineProperties(SpriteMaskFilter.prototype, { - /** - * The texture used for the displacement map. Must be power of 2 sized texture. - * - * @member {PIXI.Texture} - * @memberof PIXI.SpriteMaskFilter# - */ - map: { - get: function () - { - return this.uniforms.mask.value; - }, - set: function (value) - { - this.uniforms.mask.value = value; - } - }, - - /** - * The offset used to move the displacement map. - * - * @member {PIXI.Point} - * @memberof PIXI.SpriteMaskFilter# - */ - offset: { - get: function() - { - return this.uniforms.offset.value; - }, - set: function(value) - { - this.uniforms.offset.value = value; - } - } -}); diff --git a/src/core/renderers/webgl/filters/defaultValue.js b/src/core/renderers/webgl/filters/defaultValue.js deleted file mode 100644 index bcb27f5..0000000 --- a/src/core/renderers/webgl/filters/defaultValue.js +++ /dev/null @@ -1,74 +0,0 @@ - - -var defaultValue = function(type, size) -{ - switch (type) - { - case 'float': - return 0; - - case 'vec2': - return new Float32Array(2 * size); - - case 'vec3': - return new Float32Array(3 * size); - - case 'vec4': - return new Float32Array(4 * size); - - case 'int': - case 'sampler2D': - return 0; - - case 'ivec2': - return new Int32Array(2 * size); - - case 'ivec3': - return new Int32Array(3 * size); - - case 'ivec4': - return new Int32Array(4 * size); - - case 'bool': - return false; - - case 'bvec2': - - return booleanArray( 2 * size); - - case 'bvec3': - return booleanArray(3 * size); - - case 'bvec4': - return booleanArray(4 * size); - - case 'mat2': - return new Float32Array([1, 0 - ,0, 1]); - - case 'mat3': - return new Float32Array([1, 0, 0 - ,0, 1, 0 - ,0, 0, 1]); - - case 'mat4': - return new Float32Array([1, 0, 0, 0 - ,0, 1, 0, 0 - ,0, 0, 1, 0 - ,0, 0, 0, 1]); - } -} - -var booleanArray = function(size) -{ - var array = new Array(size); - - for (var i = 0; i < array.length; i++) - { - array[i] = false; - }; - - return array; -} - -module.exports = defaultValue; diff --git a/src/core/renderers/webgl/filters/shaderParser.js b/src/core/renderers/webgl/filters/shaderParser.js deleted file mode 100644 index 9a94af6..0000000 --- a/src/core/renderers/webgl/filters/shaderParser.js +++ /dev/null @@ -1,109 +0,0 @@ - -/** - * The default vertex shader source - * - * @static - * @constant - */ -var defaultVertexSrc = [ - 'precision lowp float;', - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - - 'uniform mat3 projectionMatrix;', - 'uniform mat3 otherMatrix;', - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vFilterCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy;', - ' vTextureCoord = aTextureCoord ;', - '}' -].join('\n'); - -/** - * The default fragment shader source - * - * @static - * @constant - */ -var defaultFragmentSrc = [ - 'precision lowp float;', - - 'struct Matty{', - ' float some;', - ' float dohave;', - 'float them;', - '};', - - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - 'uniform sampler2D uSampler;', - 'uniform sampler2D filterSampler;', - 'uniform Matty thing;', - - 'void main(void){', - ' vec4 masky = texture2D(filterSampler, vFilterCoord);', - ' vec4 sample = texture2D(uSampler, vTextureCoord);', - ' vec4 color;', - ' if(mod(vFilterCoord.x, 1.0) > 0.5){', - ' ', - ' color = vec4(1.0, 0.0, 0.0, 1.0) + thing.some;', - ' }', - ' else', - ' {', - ' color = vec4(0.0, 1.0, 0.0, 1.0) ;', - ' }', - // ' gl_FragColor = vec4(mod(vFilterCoord.x, 1.5), vFilterCoord.y,0.0,1.0);', - ' gl_FragColor = mix(sample, masky, 0.5);', - ' gl_FragColor *= sample.a;', - '}' -].join('\n'); - -//clean out white space tabs -var lines = defaultFragmentSrc.replace(/\s+/g,' ') - .split(/\s*;\s*/); - -function extractUniforms(vertexSrc, fragmentSrc) -{ - var fragUniforms = extractUniformsFromString(defaultFragmentSrc); - var vertUniforms = extractUniformsFromString(defaultVertexSrc); - - return Object.assign(fragUniforms, vertUniforms); -} - -function mergeObject(object1, object2) -{ - return Object.assign({}, object1, object2); -} - - -function extractUniformsFromString(string) -{ - var uniforms = {}; - - // clean the lines a little - remove extra spaces / teabs etc - // then split along ';' - var lines = string.replace(/\s+/g,' ') - .split(/\s*;\s*/); - - - // loop through.. - for (var i = 0; i < lines.length; i++) - { - var line = lines[i].trim(); - - if(line.indexOf('uniform') > -1) - { - var splitLine = line.split(' '); - var type = splitLine[1]; - var name = splitLine[2]; - console.log(name + " is of type " + type); - uniforms[name] = 0; - } - - return uniforms; - }; -} -//console.log(lines); diff --git a/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js new file mode 100644 index 0000000..f961c94 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js @@ -0,0 +1,50 @@ +var Filter = require('../Filter'), + math = require('../../../../math'); + +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * The SpriteMaskFilter class + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * @param sprite {PIXI.Sprite} the target sprite + */ +function SpriteMaskFilter(sprite) +{ + var maskMatrix = new math.Matrix(); + + Filter.call(this, + fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), + fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8') + ); + + sprite.renderable = false; + + this.maskSprite = sprite; + this.maskMatrix = maskMatrix; +} + +SpriteMaskFilter.prototype = Object.create(Filter.prototype); +SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; +module.exports = SpriteMaskFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +SpriteMaskFilter.prototype.apply = function (filterManager, input, output) +{ + var maskSprite = this.maskSprite; + + this.uniforms.mask = maskSprite._texture; + this.uniforms.otherMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, maskSprite ); + this.uniforms.alpha = maskSprite.worldAlpha; + + filterManager.applyFilter(this, input, output); +}; diff --git a/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag new file mode 100644 index 0000000..690dab0 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag @@ -0,0 +1,20 @@ +precision lowp float; + +varying vec2 vMaskCoord; +varying vec2 vTextureCoord; + +uniform sampler2D uSampler; +uniform float alpha; +uniform sampler2D mask; + +void main(void) +{ + // check clip! this will stop the mask bleeding out from the edges + vec2 text = abs( vMaskCoord - 0.5 ); + text = step(0.5, text); + float clip = 1.0 - max(text.y, text.x); + vec4 original = texture2D(uSampler, vTextureCoord); + vec4 masky = texture2D(mask, vMaskCoord); + original *= (masky.r * masky.a * alpha * clip); + gl_FragColor = original; +} diff --git a/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert new file mode 100644 index 0000000..b864112 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert @@ -0,0 +1,15 @@ +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; + +uniform mat3 projectionMatrix; +uniform mat3 otherMatrix; + +varying vec2 vMaskCoord; +varying vec2 vTextureCoord; + +void main(void) +{ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy; +} diff --git a/src/core/renderers/webgl/filters/spriteMaskFilter.frag b/src/core/renderers/webgl/filters/spriteMaskFilter.frag deleted file mode 100644 index ff8880c..0000000 --- a/src/core/renderers/webgl/filters/spriteMaskFilter.frag +++ /dev/null @@ -1,21 +0,0 @@ -precision lowp float; - -varying vec2 vMaskCoord; -varying vec2 vTextureCoord; -varying vec4 vColor; - -uniform sampler2D uSampler; -uniform float alpha; -uniform sampler2D mask; - -void main(void) -{ - // check clip! this will stop the mask bleeding out from the edges - vec2 text = abs( vMaskCoord - 0.5 ); - text = step(0.5, text); - float clip = 1.0 - max(text.y, text.x); - vec4 original = texture2D(uSampler, vTextureCoord); - vec4 masky = texture2D(mask, vMaskCoord); - original *= (masky.r * masky.a * alpha * clip); - gl_FragColor = original; -} diff --git a/src/core/renderers/webgl/filters/spriteMaskFilter.vert b/src/core/renderers/webgl/filters/spriteMaskFilter.vert deleted file mode 100644 index 5299c1f..0000000 --- a/src/core/renderers/webgl/filters/spriteMaskFilter.vert +++ /dev/null @@ -1,18 +0,0 @@ -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform mat3 otherMatrix; - -varying vec2 vMaskCoord; -varying vec2 vTextureCoord; -varying vec4 vColor; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); -} diff --git a/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js b/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js index 4d0221a..7d460f4 100644 --- a/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js +++ b/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js @@ -2,7 +2,6 @@ RenderTarget = require('../utils/RenderTarget'), CONST = require('../../../const'), Quad = require('../utils/Quad'), - FilterShader = require('../filters/FilterShader'), math = require('../../../math'), utils = require('../../../utils'), Shader = require('pixi-gl-core').GLShader, @@ -21,10 +20,8 @@ { WebGLManager.call(this, renderer); - // TODO - not really required. but useful for setting the quad.. - this.filterShader = new FilterShader(renderer.gl); // know about sprites! - this.quad = new Quad(gl, this.filterShader); + this.quad = new Quad(gl); this.stack = [{ target:null, @@ -90,7 +87,7 @@ { var gl = this.renderer.gl; - + var lastState = this.stack[this.stackIndex-1]; var currentState = this.stack[this.stackIndex]; this.quad.map(currentState.renderTarget.size, currentState.sourceFrame).upload(); @@ -98,7 +95,6 @@ var filter = currentState.filters[0]; // lets get the last state as that contains the renderTarget we need to render too - var lastState = this.stack[this.stackIndex-1]; filter.apply(this, currentState.renderTarget, lastState.renderTarget, false); // return the texture.. diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 2f3100b..5b1940e 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,5 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../filters/SpriteMaskFilter'); + AlphaMaskFilter = require('../filters/spriteMask/SpriteMaskFilter'); /** * @class diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.frag b/src/core/renderers/webgl/filters/FXAA/FXAA.frag new file mode 100755 index 0000000..2f3b3ae --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.frag @@ -0,0 +1,127 @@ +precision lowp float; + + +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. + +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +varying vec2 vTextureCoord; +varying vec4 vColor; +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + +uniform sampler2D uSampler; + + +void main(void){ + + gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.vert b/src/core/renderers/webgl/filters/FXAA/FXAA.vert new file mode 100755 index 0000000..b0c1860 --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.vert @@ -0,0 +1,45 @@ + +precision mediump float; + +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; + +uniform mat3 projectionMatrix; +uniform vec2 resolution; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + + +void texcoords(vec2 fragCoord, vec2 resolution, + out vec2 v_rgbNW, out vec2 v_rgbNE, + out vec2 v_rgbSW, out vec2 v_rgbSE, + out vec2 v_rgbM) { + vec2 inverseVP = 1.0 / resolution.xy; + v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; + v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; + v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; + v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; + v_rgbM = vec2(fragCoord * inverseVP); +} + +void main(void){ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); + vResolution = resolution; + + //compute the texture coords and send them to varyings + texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js new file mode 100644 index 0000000..6d5646c --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js @@ -0,0 +1,53 @@ +var AbstractFilter = require('./AbstractFilter'); +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * + * Basic FXAA implementation based on the code on geeks3d.com with the + * modification that the texture2DLod stuff was removed since it's + * unsupported by WebGL. + * + * -- + * From: + * https://github.com/mitsuhiko/webgl-meincraft + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * + */ +function FXAAFilter() +{ + AbstractFilter.call(this, + // vertex shader + fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), + // fragment shader + fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), + // uniforms + { + resolution: { type: 'v2', value: { x: 1, y: 1 } } + } + ); + +} + +FXAAFilter.prototype = Object.create(AbstractFilter.prototype); +FXAAFilter.prototype.constructor = FXAAFilter; +module.exports = FXAAFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +FXAAFilter.prototype.applyFilter = function (renderer, input, output) +{ + var filterManager = renderer.filterManager; + + var shader = this.getShader( renderer ); + // draw the filter... + filterManager.applyFilter(shader, input, output); +}; diff --git a/src/core/renderers/webgl/filters/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAAFilter.js deleted file mode 100644 index 6d5646c..0000000 --- a/src/core/renderers/webgl/filters/FXAAFilter.js +++ /dev/null @@ -1,53 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'); -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * - * Basic FXAA implementation based on the code on geeks3d.com with the - * modification that the texture2DLod stuff was removed since it's - * unsupported by WebGL. - * - * -- - * From: - * https://github.com/mitsuhiko/webgl-meincraft - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * - */ -function FXAAFilter() -{ - AbstractFilter.call(this, - // vertex shader - fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), - // fragment shader - fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), - // uniforms - { - resolution: { type: 'v2', value: { x: 1, y: 1 } } - } - ); - -} - -FXAAFilter.prototype = Object.create(AbstractFilter.prototype); -FXAAFilter.prototype.constructor = FXAAFilter; -module.exports = FXAAFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -FXAAFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - var shader = this.getShader( renderer ); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; diff --git a/src/core/renderers/webgl/filters/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/SpriteMaskFilter.js deleted file mode 100644 index ae08ea9..0000000 --- a/src/core/renderers/webgl/filters/SpriteMaskFilter.js +++ /dev/null @@ -1,95 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'), - math = require('../../../math'); - -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * The SpriteMaskFilter class - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * @param sprite {PIXI.Sprite} the target sprite - */ -function SpriteMaskFilter(sprite) -{ - var maskMatrix = new math.Matrix(); - - AbstractFilter.call(this, - fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), - fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8'), - { - mask: { type: 'sampler2D', value: sprite._texture }, - alpha: { type: 'f', value: 1}, - otherMatrix: { type: 'mat3', value: maskMatrix.toArray(true) } - } - ); - - this.maskSprite = sprite; - this.maskMatrix = maskMatrix; -} - -SpriteMaskFilter.prototype = Object.create(AbstractFilter.prototype); -SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; -module.exports = SpriteMaskFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -SpriteMaskFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - this.uniforms.mask.value = this.maskSprite._texture; - - filterManager.calculateMappedMatrix(input.frame, this.maskSprite, this.maskMatrix); - - this.uniforms.otherMatrix.value = this.maskMatrix.toArray(true); - this.uniforms.alpha.value = this.maskSprite.worldAlpha; - - var shader = this.getShader(renderer); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; - - -Object.defineProperties(SpriteMaskFilter.prototype, { - /** - * The texture used for the displacement map. Must be power of 2 sized texture. - * - * @member {PIXI.Texture} - * @memberof PIXI.SpriteMaskFilter# - */ - map: { - get: function () - { - return this.uniforms.mask.value; - }, - set: function (value) - { - this.uniforms.mask.value = value; - } - }, - - /** - * The offset used to move the displacement map. - * - * @member {PIXI.Point} - * @memberof PIXI.SpriteMaskFilter# - */ - offset: { - get: function() - { - return this.uniforms.offset.value; - }, - set: function(value) - { - this.uniforms.offset.value = value; - } - } -}); diff --git a/src/core/renderers/webgl/filters/defaultValue.js b/src/core/renderers/webgl/filters/defaultValue.js deleted file mode 100644 index bcb27f5..0000000 --- a/src/core/renderers/webgl/filters/defaultValue.js +++ /dev/null @@ -1,74 +0,0 @@ - - -var defaultValue = function(type, size) -{ - switch (type) - { - case 'float': - return 0; - - case 'vec2': - return new Float32Array(2 * size); - - case 'vec3': - return new Float32Array(3 * size); - - case 'vec4': - return new Float32Array(4 * size); - - case 'int': - case 'sampler2D': - return 0; - - case 'ivec2': - return new Int32Array(2 * size); - - case 'ivec3': - return new Int32Array(3 * size); - - case 'ivec4': - return new Int32Array(4 * size); - - case 'bool': - return false; - - case 'bvec2': - - return booleanArray( 2 * size); - - case 'bvec3': - return booleanArray(3 * size); - - case 'bvec4': - return booleanArray(4 * size); - - case 'mat2': - return new Float32Array([1, 0 - ,0, 1]); - - case 'mat3': - return new Float32Array([1, 0, 0 - ,0, 1, 0 - ,0, 0, 1]); - - case 'mat4': - return new Float32Array([1, 0, 0, 0 - ,0, 1, 0, 0 - ,0, 0, 1, 0 - ,0, 0, 0, 1]); - } -} - -var booleanArray = function(size) -{ - var array = new Array(size); - - for (var i = 0; i < array.length; i++) - { - array[i] = false; - }; - - return array; -} - -module.exports = defaultValue; diff --git a/src/core/renderers/webgl/filters/shaderParser.js b/src/core/renderers/webgl/filters/shaderParser.js deleted file mode 100644 index 9a94af6..0000000 --- a/src/core/renderers/webgl/filters/shaderParser.js +++ /dev/null @@ -1,109 +0,0 @@ - -/** - * The default vertex shader source - * - * @static - * @constant - */ -var defaultVertexSrc = [ - 'precision lowp float;', - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - - 'uniform mat3 projectionMatrix;', - 'uniform mat3 otherMatrix;', - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vFilterCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy;', - ' vTextureCoord = aTextureCoord ;', - '}' -].join('\n'); - -/** - * The default fragment shader source - * - * @static - * @constant - */ -var defaultFragmentSrc = [ - 'precision lowp float;', - - 'struct Matty{', - ' float some;', - ' float dohave;', - 'float them;', - '};', - - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - 'uniform sampler2D uSampler;', - 'uniform sampler2D filterSampler;', - 'uniform Matty thing;', - - 'void main(void){', - ' vec4 masky = texture2D(filterSampler, vFilterCoord);', - ' vec4 sample = texture2D(uSampler, vTextureCoord);', - ' vec4 color;', - ' if(mod(vFilterCoord.x, 1.0) > 0.5){', - ' ', - ' color = vec4(1.0, 0.0, 0.0, 1.0) + thing.some;', - ' }', - ' else', - ' {', - ' color = vec4(0.0, 1.0, 0.0, 1.0) ;', - ' }', - // ' gl_FragColor = vec4(mod(vFilterCoord.x, 1.5), vFilterCoord.y,0.0,1.0);', - ' gl_FragColor = mix(sample, masky, 0.5);', - ' gl_FragColor *= sample.a;', - '}' -].join('\n'); - -//clean out white space tabs -var lines = defaultFragmentSrc.replace(/\s+/g,' ') - .split(/\s*;\s*/); - -function extractUniforms(vertexSrc, fragmentSrc) -{ - var fragUniforms = extractUniformsFromString(defaultFragmentSrc); - var vertUniforms = extractUniformsFromString(defaultVertexSrc); - - return Object.assign(fragUniforms, vertUniforms); -} - -function mergeObject(object1, object2) -{ - return Object.assign({}, object1, object2); -} - - -function extractUniformsFromString(string) -{ - var uniforms = {}; - - // clean the lines a little - remove extra spaces / teabs etc - // then split along ';' - var lines = string.replace(/\s+/g,' ') - .split(/\s*;\s*/); - - - // loop through.. - for (var i = 0; i < lines.length; i++) - { - var line = lines[i].trim(); - - if(line.indexOf('uniform') > -1) - { - var splitLine = line.split(' '); - var type = splitLine[1]; - var name = splitLine[2]; - console.log(name + " is of type " + type); - uniforms[name] = 0; - } - - return uniforms; - }; -} -//console.log(lines); diff --git a/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js new file mode 100644 index 0000000..f961c94 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js @@ -0,0 +1,50 @@ +var Filter = require('../Filter'), + math = require('../../../../math'); + +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * The SpriteMaskFilter class + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * @param sprite {PIXI.Sprite} the target sprite + */ +function SpriteMaskFilter(sprite) +{ + var maskMatrix = new math.Matrix(); + + Filter.call(this, + fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), + fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8') + ); + + sprite.renderable = false; + + this.maskSprite = sprite; + this.maskMatrix = maskMatrix; +} + +SpriteMaskFilter.prototype = Object.create(Filter.prototype); +SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; +module.exports = SpriteMaskFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +SpriteMaskFilter.prototype.apply = function (filterManager, input, output) +{ + var maskSprite = this.maskSprite; + + this.uniforms.mask = maskSprite._texture; + this.uniforms.otherMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, maskSprite ); + this.uniforms.alpha = maskSprite.worldAlpha; + + filterManager.applyFilter(this, input, output); +}; diff --git a/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag new file mode 100644 index 0000000..690dab0 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag @@ -0,0 +1,20 @@ +precision lowp float; + +varying vec2 vMaskCoord; +varying vec2 vTextureCoord; + +uniform sampler2D uSampler; +uniform float alpha; +uniform sampler2D mask; + +void main(void) +{ + // check clip! this will stop the mask bleeding out from the edges + vec2 text = abs( vMaskCoord - 0.5 ); + text = step(0.5, text); + float clip = 1.0 - max(text.y, text.x); + vec4 original = texture2D(uSampler, vTextureCoord); + vec4 masky = texture2D(mask, vMaskCoord); + original *= (masky.r * masky.a * alpha * clip); + gl_FragColor = original; +} diff --git a/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert new file mode 100644 index 0000000..b864112 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert @@ -0,0 +1,15 @@ +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; + +uniform mat3 projectionMatrix; +uniform mat3 otherMatrix; + +varying vec2 vMaskCoord; +varying vec2 vTextureCoord; + +void main(void) +{ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy; +} diff --git a/src/core/renderers/webgl/filters/spriteMaskFilter.frag b/src/core/renderers/webgl/filters/spriteMaskFilter.frag deleted file mode 100644 index ff8880c..0000000 --- a/src/core/renderers/webgl/filters/spriteMaskFilter.frag +++ /dev/null @@ -1,21 +0,0 @@ -precision lowp float; - -varying vec2 vMaskCoord; -varying vec2 vTextureCoord; -varying vec4 vColor; - -uniform sampler2D uSampler; -uniform float alpha; -uniform sampler2D mask; - -void main(void) -{ - // check clip! this will stop the mask bleeding out from the edges - vec2 text = abs( vMaskCoord - 0.5 ); - text = step(0.5, text); - float clip = 1.0 - max(text.y, text.x); - vec4 original = texture2D(uSampler, vTextureCoord); - vec4 masky = texture2D(mask, vMaskCoord); - original *= (masky.r * masky.a * alpha * clip); - gl_FragColor = original; -} diff --git a/src/core/renderers/webgl/filters/spriteMaskFilter.vert b/src/core/renderers/webgl/filters/spriteMaskFilter.vert deleted file mode 100644 index 5299c1f..0000000 --- a/src/core/renderers/webgl/filters/spriteMaskFilter.vert +++ /dev/null @@ -1,18 +0,0 @@ -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform mat3 otherMatrix; - -varying vec2 vMaskCoord; -varying vec2 vTextureCoord; -varying vec4 vColor; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); -} diff --git a/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js b/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js index 4d0221a..7d460f4 100644 --- a/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js +++ b/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js @@ -2,7 +2,6 @@ RenderTarget = require('../utils/RenderTarget'), CONST = require('../../../const'), Quad = require('../utils/Quad'), - FilterShader = require('../filters/FilterShader'), math = require('../../../math'), utils = require('../../../utils'), Shader = require('pixi-gl-core').GLShader, @@ -21,10 +20,8 @@ { WebGLManager.call(this, renderer); - // TODO - not really required. but useful for setting the quad.. - this.filterShader = new FilterShader(renderer.gl); // know about sprites! - this.quad = new Quad(gl, this.filterShader); + this.quad = new Quad(gl); this.stack = [{ target:null, @@ -90,7 +87,7 @@ { var gl = this.renderer.gl; - + var lastState = this.stack[this.stackIndex-1]; var currentState = this.stack[this.stackIndex]; this.quad.map(currentState.renderTarget.size, currentState.sourceFrame).upload(); @@ -98,7 +95,6 @@ var filter = currentState.filters[0]; // lets get the last state as that contains the renderTarget we need to render too - var lastState = this.stack[this.stackIndex-1]; filter.apply(this, currentState.renderTarget, lastState.renderTarget, false); // return the texture.. diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 2f3100b..5b1940e 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,5 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../filters/SpriteMaskFilter'); + AlphaMaskFilter = require('../filters/spriteMask/SpriteMaskFilter'); /** * @class diff --git a/src/core/renderers/webgl/utils/Quad copy.js b/src/core/renderers/webgl/utils/Quad copy.js deleted file mode 100644 index ccb0962..0000000 --- a/src/core/renderers/webgl/utils/Quad copy.js +++ /dev/null @@ -1,153 +0,0 @@ -/** - * Helper class to create a quad - * - * @class - * @memberof PIXI - * @param gl {WebGLRenderingContext} The gl context for this quad to use. - */ -function Quad(gl) -{ - /* - * the current WebGL drawing context - * - * @member {WebGLRenderingContext} - */ - this.gl = gl; - -// this.textures = new TextureUvs(); - - /** - * An array of vertices - * - * @member {Float32Array} - */ - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - /** - * The Uvs of the quad - * - * @member {Float32Array} - */ - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - -// var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - //TODO convert this to a 32 unsigned int array - /** - * The color components of the triangles - * - * @member {Float32Array} - */ - this.colors = new Float32Array([ - 1,1,1,1, - 1,1,1,1, - 1,1,1,1, - 1,1,1,1 - ]); - - /* - * @member {Uint16Array} An array containing the indices of the vertices - */ - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - /* - * @member {WebGLBuffer} The vertex buffer - */ - this.vertexBuffer = gl.createBuffer(); - - /* - * @member {WebGLBuffer} The index buffer - */ - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 16) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -/** - * Maps two Rectangle to the quad - * @param rect {PIXI.Rectangle} the first rectangle - * @param rect2 {PIXI.Rectangle} the second rectangle - */ -Quad.prototype.map = function(rect, rect2) -{ - var x = 0; //rect2.x / rect.width; - var y = 0; //rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -}; - -/** - * Binds the buffer and uploads the data - */ -Quad.prototype.upload = function() -{ - var gl = this.gl; - - // TODO could probably be pushed into one upload! - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -}; - -Quad.prototype.destroy = function() -{ - var gl = this.gl; - - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.indexBuffer); -}; - -module.exports = Quad; - - diff --git a/src/core/index.js b/src/core/index.js index 0730298..fc5e48f 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -54,9 +54,7 @@ RenderTarget: require('./renderers/webgl/utils/RenderTarget'), // filters - webgl - AbstractFilter: require('./renderers/webgl/filters/AbstractFilter'), - FXAAFilter: require('./renderers/webgl/filters/FXAAFilter'), - SpriteMaskFilter: require('./renderers/webgl/filters/SpriteMaskFilter'), + SpriteMaskFilter: require('./renderers/webgl/filters/spriteMask/SpriteMaskFilter'), Filter: require('./renderers/webgl/filters/Filter'), glCore: require('pixi-gl-core'), diff --git a/src/core/renderers/webgl/filters/AbstractFilter.js b/src/core/renderers/webgl/filters/AbstractFilter.js deleted file mode 100644 index 735b31a..0000000 --- a/src/core/renderers/webgl/filters/AbstractFilter.js +++ /dev/null @@ -1,110 +0,0 @@ -var DefaultShader = require('../shaders/TextureShader'); - -/** - * This is the base class for creating a PIXI filter. Currently only WebGL supports filters. - * If you want to make a custom filter this should be your base class. - * - * @class - * @memberof PIXI - * @param vertexSrc {string|string[]} The vertex shader source as an array of strings. - * @param fragmentSrc {string|string[]} The fragment shader source as an array of strings. - * @param uniforms {object} An object containing the uniforms for this filter. - */ -function AbstractFilter(vertexSrc, fragmentSrc, uniforms) -{ - - /** - * An array of shaders - * @member {PIXI.Shader[]} - * @private - */ - this.shaders = []; - - /** - * The extra padding that the filter might need - * @member {number} - */ - this.padding = 0; - - /** - * The uniforms as an object - * @member {object} - */ - this.uniforms = uniforms || {}; - - - /** - * The code of the vertex shader - * @member {string[]} - * @private - */ - this.vertexSrc = vertexSrc || DefaultShader.defaultVertexSrc; - - /** - * The code of the frament shader - * @member {string[]} - * @private - */ - this.fragmentSrc = fragmentSrc || DefaultShader.defaultFragmentSrc; - - //TODO a reminder - would be cool to have lower res filters as this would give better performance. - - //typeof fragmentSrc === 'string' ? fragmentSrc.split('') : (fragmentSrc || []); - -} - -AbstractFilter.prototype.constructor = AbstractFilter; -module.exports = AbstractFilter; - -/** - * Grabs a shader from the current renderer - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the shader from - */ -AbstractFilter.prototype.getShader = function (renderer) -{ - var gl = renderer.gl; - - var shader = this.shaders[gl.id]; - - if (!shader) - { - shader = new DefaultShader(renderer.shaderManager, - this.vertexSrc, - this.fragmentSrc, - this.uniforms, - this.attributes - ); - - this.shaders[gl.id] = shader; - } - - return shader; -}; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - * @param clear {boolean} Whether or not we want to clear the outputTarget - */ -AbstractFilter.prototype.applyFilter = function (renderer, input, output, clear) -{ - var shader = this.getShader(renderer); - - renderer.filterManager.applyFilter(shader, input, output, clear); -}; - -/** - * Syncs a uniform between the class object and the shaders. - * - */ -AbstractFilter.prototype.syncUniform = function (uniform) -{ - for (var i = 0, j = this.shaders.length; i < j; ++i) - { - this.shaders[i].syncUniform(uniform); - } -}; diff --git a/src/core/renderers/webgl/filters/FXAA.frag b/src/core/renderers/webgl/filters/FXAA.frag deleted file mode 100755 index 2f3b3ae..0000000 --- a/src/core/renderers/webgl/filters/FXAA.frag +++ /dev/null @@ -1,127 +0,0 @@ -precision lowp float; - - -/** -Basic FXAA implementation based on the code on geeks3d.com with the -modification that the texture2DLod stuff was removed since it's -unsupported by WebGL. - --- - -From: -https://github.com/mitsuhiko/webgl-meincraft - -Copyright (c) 2011 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FXAA_REDUCE_MIN - #define FXAA_REDUCE_MIN (1.0/ 128.0) -#endif -#ifndef FXAA_REDUCE_MUL - #define FXAA_REDUCE_MUL (1.0 / 8.0) -#endif -#ifndef FXAA_SPAN_MAX - #define FXAA_SPAN_MAX 8.0 -#endif - -//optimized version for mobile, where dependent -//texture reads can be a bottleneck -vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, - vec2 v_rgbNW, vec2 v_rgbNE, - vec2 v_rgbSW, vec2 v_rgbSE, - vec2 v_rgbM) { - vec4 color; - mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); - vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; - vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; - vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; - vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; - vec4 texColor = texture2D(tex, v_rgbM); - vec3 rgbM = texColor.xyz; - vec3 luma = vec3(0.299, 0.587, 0.114); - float lumaNW = dot(rgbNW, luma); - float lumaNE = dot(rgbNE, luma); - float lumaSW = dot(rgbSW, luma); - float lumaSE = dot(rgbSE, luma); - float lumaM = dot(rgbM, luma); - float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); - float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - - mediump vec2 dir; - dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); - dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); - - float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * - (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); - - float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); - dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), - max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), - dir * rcpDirMin)) * inverseVP; - - vec3 rgbA = 0.5 * ( - texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + - texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); - vec3 rgbB = rgbA * 0.5 + 0.25 * ( - texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + - texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); - - float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) - color = vec4(rgbA, texColor.a); - else - color = vec4(rgbB, texColor.a); - return color; -} - - -varying vec2 vTextureCoord; -varying vec4 vColor; -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - -uniform sampler2D uSampler; - - -void main(void){ - - gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); - -} diff --git a/src/core/renderers/webgl/filters/FXAA.vert b/src/core/renderers/webgl/filters/FXAA.vert deleted file mode 100755 index b0c1860..0000000 --- a/src/core/renderers/webgl/filters/FXAA.vert +++ /dev/null @@ -1,45 +0,0 @@ - -precision mediump float; - -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform vec2 resolution; - -varying vec2 vTextureCoord; -varying vec4 vColor; - -varying vec2 vResolution; - -//texcoords computed in vertex step -//to avoid dependent texture reads -varying vec2 v_rgbNW; -varying vec2 v_rgbNE; -varying vec2 v_rgbSW; -varying vec2 v_rgbSE; -varying vec2 v_rgbM; - - -void texcoords(vec2 fragCoord, vec2 resolution, - out vec2 v_rgbNW, out vec2 v_rgbNE, - out vec2 v_rgbSW, out vec2 v_rgbSE, - out vec2 v_rgbM) { - vec2 inverseVP = 1.0 / resolution.xy; - v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; - v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; - v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; - v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; - v_rgbM = vec2(fragCoord * inverseVP); -} - -void main(void){ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); - vResolution = resolution; - - //compute the texture coords and send them to varyings - texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); -} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.frag b/src/core/renderers/webgl/filters/FXAA/FXAA.frag new file mode 100755 index 0000000..2f3b3ae --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.frag @@ -0,0 +1,127 @@ +precision lowp float; + + +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. + +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +varying vec2 vTextureCoord; +varying vec4 vColor; +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + +uniform sampler2D uSampler; + + +void main(void){ + + gl_FragColor = fxaa(uSampler, vTextureCoord * vResolution, vResolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAA.vert b/src/core/renderers/webgl/filters/FXAA/FXAA.vert new file mode 100755 index 0000000..b0c1860 --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAA.vert @@ -0,0 +1,45 @@ + +precision mediump float; + +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; + +uniform mat3 projectionMatrix; +uniform vec2 resolution; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +varying vec2 vResolution; + +//texcoords computed in vertex step +//to avoid dependent texture reads +varying vec2 v_rgbNW; +varying vec2 v_rgbNE; +varying vec2 v_rgbSW; +varying vec2 v_rgbSE; +varying vec2 v_rgbM; + + +void texcoords(vec2 fragCoord, vec2 resolution, + out vec2 v_rgbNW, out vec2 v_rgbNE, + out vec2 v_rgbSW, out vec2 v_rgbSE, + out vec2 v_rgbM) { + vec2 inverseVP = 1.0 / resolution.xy; + v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; + v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; + v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; + v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; + v_rgbM = vec2(fragCoord * inverseVP); +} + +void main(void){ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); + vResolution = resolution; + + //compute the texture coords and send them to varyings + texcoords(aTextureCoord * resolution, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); +} diff --git a/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js new file mode 100644 index 0000000..6d5646c --- /dev/null +++ b/src/core/renderers/webgl/filters/FXAA/FXAAFilter.js @@ -0,0 +1,53 @@ +var AbstractFilter = require('./AbstractFilter'); +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * + * Basic FXAA implementation based on the code on geeks3d.com with the + * modification that the texture2DLod stuff was removed since it's + * unsupported by WebGL. + * + * -- + * From: + * https://github.com/mitsuhiko/webgl-meincraft + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * + */ +function FXAAFilter() +{ + AbstractFilter.call(this, + // vertex shader + fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), + // fragment shader + fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), + // uniforms + { + resolution: { type: 'v2', value: { x: 1, y: 1 } } + } + ); + +} + +FXAAFilter.prototype = Object.create(AbstractFilter.prototype); +FXAAFilter.prototype.constructor = FXAAFilter; +module.exports = FXAAFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +FXAAFilter.prototype.applyFilter = function (renderer, input, output) +{ + var filterManager = renderer.filterManager; + + var shader = this.getShader( renderer ); + // draw the filter... + filterManager.applyFilter(shader, input, output); +}; diff --git a/src/core/renderers/webgl/filters/FXAAFilter.js b/src/core/renderers/webgl/filters/FXAAFilter.js deleted file mode 100644 index 6d5646c..0000000 --- a/src/core/renderers/webgl/filters/FXAAFilter.js +++ /dev/null @@ -1,53 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'); -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * - * Basic FXAA implementation based on the code on geeks3d.com with the - * modification that the texture2DLod stuff was removed since it's - * unsupported by WebGL. - * - * -- - * From: - * https://github.com/mitsuhiko/webgl-meincraft - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * - */ -function FXAAFilter() -{ - AbstractFilter.call(this, - // vertex shader - fs.readFileSync(__dirname + '/FXAA.vert', 'utf8'), - // fragment shader - fs.readFileSync(__dirname + '/FXAA.frag', 'utf8'), - // uniforms - { - resolution: { type: 'v2', value: { x: 1, y: 1 } } - } - ); - -} - -FXAAFilter.prototype = Object.create(AbstractFilter.prototype); -FXAAFilter.prototype.constructor = FXAAFilter; -module.exports = FXAAFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -FXAAFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - var shader = this.getShader( renderer ); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; diff --git a/src/core/renderers/webgl/filters/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/SpriteMaskFilter.js deleted file mode 100644 index ae08ea9..0000000 --- a/src/core/renderers/webgl/filters/SpriteMaskFilter.js +++ /dev/null @@ -1,95 +0,0 @@ -var AbstractFilter = require('./AbstractFilter'), - math = require('../../../math'); - -// @see https://github.com/substack/brfs/issues/25 -var fs = require('fs'); - -/** - * The SpriteMaskFilter class - * - * @class - * @extends PIXI.AbstractFilter - * @memberof PIXI - * @param sprite {PIXI.Sprite} the target sprite - */ -function SpriteMaskFilter(sprite) -{ - var maskMatrix = new math.Matrix(); - - AbstractFilter.call(this, - fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), - fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8'), - { - mask: { type: 'sampler2D', value: sprite._texture }, - alpha: { type: 'f', value: 1}, - otherMatrix: { type: 'mat3', value: maskMatrix.toArray(true) } - } - ); - - this.maskSprite = sprite; - this.maskMatrix = maskMatrix; -} - -SpriteMaskFilter.prototype = Object.create(AbstractFilter.prototype); -SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; -module.exports = SpriteMaskFilter; - -/** - * Applies the filter - * - * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from - * @param input {PIXI.RenderTarget} - * @param output {PIXI.RenderTarget} - */ -SpriteMaskFilter.prototype.applyFilter = function (renderer, input, output) -{ - var filterManager = renderer.filterManager; - - this.uniforms.mask.value = this.maskSprite._texture; - - filterManager.calculateMappedMatrix(input.frame, this.maskSprite, this.maskMatrix); - - this.uniforms.otherMatrix.value = this.maskMatrix.toArray(true); - this.uniforms.alpha.value = this.maskSprite.worldAlpha; - - var shader = this.getShader(renderer); - // draw the filter... - filterManager.applyFilter(shader, input, output); -}; - - -Object.defineProperties(SpriteMaskFilter.prototype, { - /** - * The texture used for the displacement map. Must be power of 2 sized texture. - * - * @member {PIXI.Texture} - * @memberof PIXI.SpriteMaskFilter# - */ - map: { - get: function () - { - return this.uniforms.mask.value; - }, - set: function (value) - { - this.uniforms.mask.value = value; - } - }, - - /** - * The offset used to move the displacement map. - * - * @member {PIXI.Point} - * @memberof PIXI.SpriteMaskFilter# - */ - offset: { - get: function() - { - return this.uniforms.offset.value; - }, - set: function(value) - { - this.uniforms.offset.value = value; - } - } -}); diff --git a/src/core/renderers/webgl/filters/defaultValue.js b/src/core/renderers/webgl/filters/defaultValue.js deleted file mode 100644 index bcb27f5..0000000 --- a/src/core/renderers/webgl/filters/defaultValue.js +++ /dev/null @@ -1,74 +0,0 @@ - - -var defaultValue = function(type, size) -{ - switch (type) - { - case 'float': - return 0; - - case 'vec2': - return new Float32Array(2 * size); - - case 'vec3': - return new Float32Array(3 * size); - - case 'vec4': - return new Float32Array(4 * size); - - case 'int': - case 'sampler2D': - return 0; - - case 'ivec2': - return new Int32Array(2 * size); - - case 'ivec3': - return new Int32Array(3 * size); - - case 'ivec4': - return new Int32Array(4 * size); - - case 'bool': - return false; - - case 'bvec2': - - return booleanArray( 2 * size); - - case 'bvec3': - return booleanArray(3 * size); - - case 'bvec4': - return booleanArray(4 * size); - - case 'mat2': - return new Float32Array([1, 0 - ,0, 1]); - - case 'mat3': - return new Float32Array([1, 0, 0 - ,0, 1, 0 - ,0, 0, 1]); - - case 'mat4': - return new Float32Array([1, 0, 0, 0 - ,0, 1, 0, 0 - ,0, 0, 1, 0 - ,0, 0, 0, 1]); - } -} - -var booleanArray = function(size) -{ - var array = new Array(size); - - for (var i = 0; i < array.length; i++) - { - array[i] = false; - }; - - return array; -} - -module.exports = defaultValue; diff --git a/src/core/renderers/webgl/filters/shaderParser.js b/src/core/renderers/webgl/filters/shaderParser.js deleted file mode 100644 index 9a94af6..0000000 --- a/src/core/renderers/webgl/filters/shaderParser.js +++ /dev/null @@ -1,109 +0,0 @@ - -/** - * The default vertex shader source - * - * @static - * @constant - */ -var defaultVertexSrc = [ - 'precision lowp float;', - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - - 'uniform mat3 projectionMatrix;', - 'uniform mat3 otherMatrix;', - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - - 'void main(void){', - ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', - ' vFilterCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy;', - ' vTextureCoord = aTextureCoord ;', - '}' -].join('\n'); - -/** - * The default fragment shader source - * - * @static - * @constant - */ -var defaultFragmentSrc = [ - 'precision lowp float;', - - 'struct Matty{', - ' float some;', - ' float dohave;', - 'float them;', - '};', - - 'varying vec2 vTextureCoord;', - 'varying vec2 vFilterCoord;', - 'uniform sampler2D uSampler;', - 'uniform sampler2D filterSampler;', - 'uniform Matty thing;', - - 'void main(void){', - ' vec4 masky = texture2D(filterSampler, vFilterCoord);', - ' vec4 sample = texture2D(uSampler, vTextureCoord);', - ' vec4 color;', - ' if(mod(vFilterCoord.x, 1.0) > 0.5){', - ' ', - ' color = vec4(1.0, 0.0, 0.0, 1.0) + thing.some;', - ' }', - ' else', - ' {', - ' color = vec4(0.0, 1.0, 0.0, 1.0) ;', - ' }', - // ' gl_FragColor = vec4(mod(vFilterCoord.x, 1.5), vFilterCoord.y,0.0,1.0);', - ' gl_FragColor = mix(sample, masky, 0.5);', - ' gl_FragColor *= sample.a;', - '}' -].join('\n'); - -//clean out white space tabs -var lines = defaultFragmentSrc.replace(/\s+/g,' ') - .split(/\s*;\s*/); - -function extractUniforms(vertexSrc, fragmentSrc) -{ - var fragUniforms = extractUniformsFromString(defaultFragmentSrc); - var vertUniforms = extractUniformsFromString(defaultVertexSrc); - - return Object.assign(fragUniforms, vertUniforms); -} - -function mergeObject(object1, object2) -{ - return Object.assign({}, object1, object2); -} - - -function extractUniformsFromString(string) -{ - var uniforms = {}; - - // clean the lines a little - remove extra spaces / teabs etc - // then split along ';' - var lines = string.replace(/\s+/g,' ') - .split(/\s*;\s*/); - - - // loop through.. - for (var i = 0; i < lines.length; i++) - { - var line = lines[i].trim(); - - if(line.indexOf('uniform') > -1) - { - var splitLine = line.split(' '); - var type = splitLine[1]; - var name = splitLine[2]; - console.log(name + " is of type " + type); - uniforms[name] = 0; - } - - return uniforms; - }; -} -//console.log(lines); diff --git a/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js new file mode 100644 index 0000000..f961c94 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/SpriteMaskFilter.js @@ -0,0 +1,50 @@ +var Filter = require('../Filter'), + math = require('../../../../math'); + +// @see https://github.com/substack/brfs/issues/25 +var fs = require('fs'); + +/** + * The SpriteMaskFilter class + * + * @class + * @extends PIXI.AbstractFilter + * @memberof PIXI + * @param sprite {PIXI.Sprite} the target sprite + */ +function SpriteMaskFilter(sprite) +{ + var maskMatrix = new math.Matrix(); + + Filter.call(this, + fs.readFileSync(__dirname + '/spriteMaskFilter.vert', 'utf8'), + fs.readFileSync(__dirname + '/spriteMaskFilter.frag', 'utf8') + ); + + sprite.renderable = false; + + this.maskSprite = sprite; + this.maskMatrix = maskMatrix; +} + +SpriteMaskFilter.prototype = Object.create(Filter.prototype); +SpriteMaskFilter.prototype.constructor = SpriteMaskFilter; +module.exports = SpriteMaskFilter; + +/** + * Applies the filter + * + * @param renderer {PIXI.WebGLRenderer} The renderer to retrieve the filter from + * @param input {PIXI.RenderTarget} + * @param output {PIXI.RenderTarget} + */ +SpriteMaskFilter.prototype.apply = function (filterManager, input, output) +{ + var maskSprite = this.maskSprite; + + this.uniforms.mask = maskSprite._texture; + this.uniforms.otherMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, maskSprite ); + this.uniforms.alpha = maskSprite.worldAlpha; + + filterManager.applyFilter(this, input, output); +}; diff --git a/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag new file mode 100644 index 0000000..690dab0 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.frag @@ -0,0 +1,20 @@ +precision lowp float; + +varying vec2 vMaskCoord; +varying vec2 vTextureCoord; + +uniform sampler2D uSampler; +uniform float alpha; +uniform sampler2D mask; + +void main(void) +{ + // check clip! this will stop the mask bleeding out from the edges + vec2 text = abs( vMaskCoord - 0.5 ); + text = step(0.5, text); + float clip = 1.0 - max(text.y, text.x); + vec4 original = texture2D(uSampler, vTextureCoord); + vec4 masky = texture2D(mask, vMaskCoord); + original *= (masky.r * masky.a * alpha * clip); + gl_FragColor = original; +} diff --git a/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert new file mode 100644 index 0000000..b864112 --- /dev/null +++ b/src/core/renderers/webgl/filters/spriteMask/spriteMaskFilter.vert @@ -0,0 +1,15 @@ +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; + +uniform mat3 projectionMatrix; +uniform mat3 otherMatrix; + +varying vec2 vMaskCoord; +varying vec2 vTextureCoord; + +void main(void) +{ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy; +} diff --git a/src/core/renderers/webgl/filters/spriteMaskFilter.frag b/src/core/renderers/webgl/filters/spriteMaskFilter.frag deleted file mode 100644 index ff8880c..0000000 --- a/src/core/renderers/webgl/filters/spriteMaskFilter.frag +++ /dev/null @@ -1,21 +0,0 @@ -precision lowp float; - -varying vec2 vMaskCoord; -varying vec2 vTextureCoord; -varying vec4 vColor; - -uniform sampler2D uSampler; -uniform float alpha; -uniform sampler2D mask; - -void main(void) -{ - // check clip! this will stop the mask bleeding out from the edges - vec2 text = abs( vMaskCoord - 0.5 ); - text = step(0.5, text); - float clip = 1.0 - max(text.y, text.x); - vec4 original = texture2D(uSampler, vTextureCoord); - vec4 masky = texture2D(mask, vMaskCoord); - original *= (masky.r * masky.a * alpha * clip); - gl_FragColor = original; -} diff --git a/src/core/renderers/webgl/filters/spriteMaskFilter.vert b/src/core/renderers/webgl/filters/spriteMaskFilter.vert deleted file mode 100644 index 5299c1f..0000000 --- a/src/core/renderers/webgl/filters/spriteMaskFilter.vert +++ /dev/null @@ -1,18 +0,0 @@ -attribute vec2 aVertexPosition; -attribute vec2 aTextureCoord; -attribute vec4 aColor; - -uniform mat3 projectionMatrix; -uniform mat3 otherMatrix; - -varying vec2 vMaskCoord; -varying vec2 vTextureCoord; -varying vec4 vColor; - -void main(void) -{ - gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); - vTextureCoord = aTextureCoord; - vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy; - vColor = vec4(aColor.rgb * aColor.a, aColor.a); -} diff --git a/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js b/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js index 4d0221a..7d460f4 100644 --- a/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js +++ b/src/core/renderers/webgl/managers/FilterManagerRoundTwo.js @@ -2,7 +2,6 @@ RenderTarget = require('../utils/RenderTarget'), CONST = require('../../../const'), Quad = require('../utils/Quad'), - FilterShader = require('../filters/FilterShader'), math = require('../../../math'), utils = require('../../../utils'), Shader = require('pixi-gl-core').GLShader, @@ -21,10 +20,8 @@ { WebGLManager.call(this, renderer); - // TODO - not really required. but useful for setting the quad.. - this.filterShader = new FilterShader(renderer.gl); // know about sprites! - this.quad = new Quad(gl, this.filterShader); + this.quad = new Quad(gl); this.stack = [{ target:null, @@ -90,7 +87,7 @@ { var gl = this.renderer.gl; - + var lastState = this.stack[this.stackIndex-1]; var currentState = this.stack[this.stackIndex]; this.quad.map(currentState.renderTarget.size, currentState.sourceFrame).upload(); @@ -98,7 +95,6 @@ var filter = currentState.filters[0]; // lets get the last state as that contains the renderTarget we need to render too - var lastState = this.stack[this.stackIndex-1]; filter.apply(this, currentState.renderTarget, lastState.renderTarget, false); // return the texture.. diff --git a/src/core/renderers/webgl/managers/MaskManager.js b/src/core/renderers/webgl/managers/MaskManager.js index 2f3100b..5b1940e 100644 --- a/src/core/renderers/webgl/managers/MaskManager.js +++ b/src/core/renderers/webgl/managers/MaskManager.js @@ -1,5 +1,5 @@ var WebGLManager = require('./WebGLManager'), - AlphaMaskFilter = require('../filters/SpriteMaskFilter'); + AlphaMaskFilter = require('../filters/spriteMask/SpriteMaskFilter'); /** * @class diff --git a/src/core/renderers/webgl/utils/Quad copy.js b/src/core/renderers/webgl/utils/Quad copy.js deleted file mode 100644 index ccb0962..0000000 --- a/src/core/renderers/webgl/utils/Quad copy.js +++ /dev/null @@ -1,153 +0,0 @@ -/** - * Helper class to create a quad - * - * @class - * @memberof PIXI - * @param gl {WebGLRenderingContext} The gl context for this quad to use. - */ -function Quad(gl) -{ - /* - * the current WebGL drawing context - * - * @member {WebGLRenderingContext} - */ - this.gl = gl; - -// this.textures = new TextureUvs(); - - /** - * An array of vertices - * - * @member {Float32Array} - */ - this.vertices = new Float32Array([ - 0,0, - 200,0, - 200,200, - 0,200 - ]); - - /** - * The Uvs of the quad - * - * @member {Float32Array} - */ - this.uvs = new Float32Array([ - 0,0, - 1,0, - 1,1, - 0,1 - ]); - -// var white = (0xFFFFFF >> 16) + (0xFFFFFF & 0xff00) + ((0xFFFFFF & 0xff) << 16) + (1 * 255 << 24); - //TODO convert this to a 32 unsigned int array - /** - * The color components of the triangles - * - * @member {Float32Array} - */ - this.colors = new Float32Array([ - 1,1,1,1, - 1,1,1,1, - 1,1,1,1, - 1,1,1,1 - ]); - - /* - * @member {Uint16Array} An array containing the indices of the vertices - */ - this.indices = new Uint16Array([ - 0, 1, 2, 0, 3, 2 - ]); - - /* - * @member {WebGLBuffer} The vertex buffer - */ - this.vertexBuffer = gl.createBuffer(); - - /* - * @member {WebGLBuffer} The index buffer - */ - this.indexBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, (8 + 8 + 16) * 4, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - this.upload(); -} - -Quad.prototype.constructor = Quad; - -/** - * Maps two Rectangle to the quad - * @param rect {PIXI.Rectangle} the first rectangle - * @param rect2 {PIXI.Rectangle} the second rectangle - */ -Quad.prototype.map = function(rect, rect2) -{ - var x = 0; //rect2.x / rect.width; - var y = 0; //rect2.y / rect.height; - - this.uvs[0] = x; - this.uvs[1] = y; - - this.uvs[2] = x + rect2.width / rect.width; - this.uvs[3] = y; - - this.uvs[4] = x + rect2.width / rect.width; - this.uvs[5] = y + rect2.height / rect.height; - - this.uvs[6] = x; - this.uvs[7] = y + rect2.height / rect.height; - - /// ----- - x = rect2.x; - y = rect2.y; - - this.vertices[0] = x; - this.vertices[1] = y; - - this.vertices[2] = x + rect2.width; - this.vertices[3] = y; - - this.vertices[4] = x + rect2.width; - this.vertices[5] = y + rect2.height; - - this.vertices[6] = x; - this.vertices[7] = y + rect2.height; - - this.upload(); -}; - -/** - * Binds the buffer and uploads the data - */ -Quad.prototype.upload = function() -{ - var gl = this.gl; - - // TODO could probably be pushed into one upload! - gl.bindBuffer( gl.ARRAY_BUFFER, this.vertexBuffer ); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - - gl.bufferSubData(gl.ARRAY_BUFFER, 8 * 4, this.uvs); - - gl.bufferSubData(gl.ARRAY_BUFFER, (8 + 8) * 4, this.colors); -}; - -Quad.prototype.destroy = function() -{ - var gl = this.gl; - - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.indexBuffer); -}; - -module.exports = Quad; - - diff --git a/src/core/renderers/webgl/utils/Quad.js b/src/core/renderers/webgl/utils/Quad.js index 69dc3dc..5f07564 100644 --- a/src/core/renderers/webgl/utils/Quad.js +++ b/src/core/renderers/webgl/utils/Quad.js @@ -8,7 +8,7 @@ * @memberof PIXI * @param gl {WebGLRenderingContext} The gl context for this quad to use. */ -function Quad(gl, shader) +function Quad(gl) { /* * the current WebGL drawing context @@ -65,11 +65,10 @@ this.vertexBuffer = glCore.GLBuffer.createVertexBuffer(gl, this.interleaved, gl.STATIC_DRAW); this.indexBuffer = glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); - this.vao = new glCore.VertexArrayObject(gl) .addIndex(this.indexBuffer) - .addAttribute(this.vertexBuffer, shader.attributes.aVertexPosition, gl.FLOAT, false, 4 * 4, 0) - .addAttribute(this.vertexBuffer, shader.attributes.aTextureCoord, gl.FLOAT, false, 4 * 4, 2 * 4) + .addAttribute(this.vertexBuffer, {type:'vec2', size:2, location:0}, gl.FLOAT, false, 4 * 4, 0) + .addAttribute(this.vertexBuffer, {type:'vec2', size:2, location:1}, gl.FLOAT, false, 4 * 4, 2 * 4) }