diff --git a/src/filters/ascii/AsciiFilter.js b/src/filters/ascii/AsciiFilter.js new file mode 100644 index 0000000..cd02f7b --- /dev/null +++ b/src/filters/ascii/AsciiFilter.js @@ -0,0 +1,52 @@ +var core = require('../../core'); +// @see https://github.com/substack/brfs/issues/25 +var glslify = require('glslify'); + +// TODO (cengler) - The Y is flipped in this shader for some reason. + +/** + * @author Vico @vicocotea + * original shader : https://www.shadertoy.com/view/lssGDj by @movAX13h + */ + +/** + * An ASCII filter. + * + * @class + * @extends PIXI.Filter + * @memberof PIXI.filters + */ +function AsciiFilter() +{ + core.Filter.call(this, + // vertex shader + glslify('../fragments/default.vert'), + // fragment shader + glslify('./ascii.frag') + ); + + this.size = 8; +} + +AsciiFilter.prototype = Object.create(core.Filter.prototype); +AsciiFilter.prototype.constructor = AsciiFilter; +module.exports = AsciiFilter; + +Object.defineProperties(AsciiFilter.prototype, { + /** + * The pixel size used by the filter. + * + * @member {number} + * @memberof PIXI.filters.AsciiFilter# + */ + size: { + get: function () + { + return this.uniforms.pixelSize; + }, + set: function (value) + { + this.uniforms.pixelSize = value; + } + } +}); diff --git a/src/filters/ascii/AsciiFilter.js b/src/filters/ascii/AsciiFilter.js new file mode 100644 index 0000000..cd02f7b --- /dev/null +++ b/src/filters/ascii/AsciiFilter.js @@ -0,0 +1,52 @@ +var core = require('../../core'); +// @see https://github.com/substack/brfs/issues/25 +var glslify = require('glslify'); + +// TODO (cengler) - The Y is flipped in this shader for some reason. + +/** + * @author Vico @vicocotea + * original shader : https://www.shadertoy.com/view/lssGDj by @movAX13h + */ + +/** + * An ASCII filter. + * + * @class + * @extends PIXI.Filter + * @memberof PIXI.filters + */ +function AsciiFilter() +{ + core.Filter.call(this, + // vertex shader + glslify('../fragments/default.vert'), + // fragment shader + glslify('./ascii.frag') + ); + + this.size = 8; +} + +AsciiFilter.prototype = Object.create(core.Filter.prototype); +AsciiFilter.prototype.constructor = AsciiFilter; +module.exports = AsciiFilter; + +Object.defineProperties(AsciiFilter.prototype, { + /** + * The pixel size used by the filter. + * + * @member {number} + * @memberof PIXI.filters.AsciiFilter# + */ + size: { + get: function () + { + return this.uniforms.pixelSize; + }, + set: function (value) + { + this.uniforms.pixelSize = value; + } + } +}); diff --git a/src/filters/ascii/ascii.frag b/src/filters/ascii/ascii.frag new file mode 100644 index 0000000..5608d6e --- /dev/null +++ b/src/filters/ascii/ascii.frag @@ -0,0 +1,70 @@ +varying vec2 vTextureCoord; + +uniform vec4 filterArea; +uniform float pixelSize; +uniform sampler2D uSampler; + +vec2 mapCoord( vec2 coord ) +{ + coord *= filterArea.xy; + coord += filterArea.zw; + + return coord; +} + +vec2 unmapCoord( vec2 coord ) +{ + coord -= filterArea.zw; + coord /= filterArea.xy; + + return coord; +} + +vec2 pixelate(vec2 coord, vec2 size) +{ + return floor( coord / size ) * size; +} + +vec2 getMod(vec2 coord, vec2 size) +{ + return mod( coord , size) / size; +} + +float character(float n, vec2 p) +{ + p = floor(p*vec2(4.0, -4.0) + 2.5); + if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y) + { + if (int(mod(n/exp2(p.x + 5.0*p.y), 2.0)) == 1) return 1.0; + } + return 0.0; +} + +void main() +{ + vec2 coord = mapCoord(vTextureCoord); + + // get the rounded color.. + vec2 pixCoord = pixelate(coord, vec2(pixelSize)); + pixCoord = unmapCoord(pixCoord); + + vec4 color = texture2D(uSampler, pixCoord); + + // determine the character to use + float gray = (color.r + color.g + color.b) / 3.0; + + float n = 65536.0; // . + if (gray > 0.2) n = 65600.0; // : + if (gray > 0.3) n = 332772.0; // * + if (gray > 0.4) n = 15255086.0; // o + if (gray > 0.5) n = 23385164.0; // & + if (gray > 0.6) n = 15252014.0; // 8 + if (gray > 0.7) n = 13199452.0; // @ + if (gray > 0.8) n = 11512810.0; // # + + // get the mod.. + vec2 modd = getMod(coord, vec2(pixelSize)); + + gl_FragColor = color * character( n, vec2(-1.0) + modd * 2.0); + +} \ No newline at end of file diff --git a/src/filters/ascii/AsciiFilter.js b/src/filters/ascii/AsciiFilter.js new file mode 100644 index 0000000..cd02f7b --- /dev/null +++ b/src/filters/ascii/AsciiFilter.js @@ -0,0 +1,52 @@ +var core = require('../../core'); +// @see https://github.com/substack/brfs/issues/25 +var glslify = require('glslify'); + +// TODO (cengler) - The Y is flipped in this shader for some reason. + +/** + * @author Vico @vicocotea + * original shader : https://www.shadertoy.com/view/lssGDj by @movAX13h + */ + +/** + * An ASCII filter. + * + * @class + * @extends PIXI.Filter + * @memberof PIXI.filters + */ +function AsciiFilter() +{ + core.Filter.call(this, + // vertex shader + glslify('../fragments/default.vert'), + // fragment shader + glslify('./ascii.frag') + ); + + this.size = 8; +} + +AsciiFilter.prototype = Object.create(core.Filter.prototype); +AsciiFilter.prototype.constructor = AsciiFilter; +module.exports = AsciiFilter; + +Object.defineProperties(AsciiFilter.prototype, { + /** + * The pixel size used by the filter. + * + * @member {number} + * @memberof PIXI.filters.AsciiFilter# + */ + size: { + get: function () + { + return this.uniforms.pixelSize; + }, + set: function (value) + { + this.uniforms.pixelSize = value; + } + } +}); diff --git a/src/filters/ascii/ascii.frag b/src/filters/ascii/ascii.frag new file mode 100644 index 0000000..5608d6e --- /dev/null +++ b/src/filters/ascii/ascii.frag @@ -0,0 +1,70 @@ +varying vec2 vTextureCoord; + +uniform vec4 filterArea; +uniform float pixelSize; +uniform sampler2D uSampler; + +vec2 mapCoord( vec2 coord ) +{ + coord *= filterArea.xy; + coord += filterArea.zw; + + return coord; +} + +vec2 unmapCoord( vec2 coord ) +{ + coord -= filterArea.zw; + coord /= filterArea.xy; + + return coord; +} + +vec2 pixelate(vec2 coord, vec2 size) +{ + return floor( coord / size ) * size; +} + +vec2 getMod(vec2 coord, vec2 size) +{ + return mod( coord , size) / size; +} + +float character(float n, vec2 p) +{ + p = floor(p*vec2(4.0, -4.0) + 2.5); + if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y) + { + if (int(mod(n/exp2(p.x + 5.0*p.y), 2.0)) == 1) return 1.0; + } + return 0.0; +} + +void main() +{ + vec2 coord = mapCoord(vTextureCoord); + + // get the rounded color.. + vec2 pixCoord = pixelate(coord, vec2(pixelSize)); + pixCoord = unmapCoord(pixCoord); + + vec4 color = texture2D(uSampler, pixCoord); + + // determine the character to use + float gray = (color.r + color.g + color.b) / 3.0; + + float n = 65536.0; // . + if (gray > 0.2) n = 65600.0; // : + if (gray > 0.3) n = 332772.0; // * + if (gray > 0.4) n = 15255086.0; // o + if (gray > 0.5) n = 23385164.0; // & + if (gray > 0.6) n = 15252014.0; // 8 + if (gray > 0.7) n = 13199452.0; // @ + if (gray > 0.8) n = 11512810.0; // # + + // get the mod.. + vec2 modd = getMod(coord, vec2(pixelSize)); + + gl_FragColor = color * character( n, vec2(-1.0) + modd * 2.0); + +} \ No newline at end of file diff --git a/src/filters/index.js b/src/filters/index.js index e480166..74d6478 100644 --- a/src/filters/index.js +++ b/src/filters/index.js @@ -9,7 +9,7 @@ * @namespace PIXI.filters */ module.exports = { - // AsciiFilter: require('./ascii/AsciiFilter'), + AsciiFilter: require('./ascii/AsciiFilter'), BloomFilter: require('./bloom/BloomFilter'), // BlurDirFilter: require('./blur/BlurDirFilter'), // ColorStepFilter: require('./color/ColorStepFilter'),