Newer
Older
pixi.js / src / filters / displacement / DisplacementFilter.js
@mathew groves mathew groves on 18 Feb 2015 3 KB Set default displacement to be 20,20
var core = require('../../core');

/**
 * The DisplacementFilter class uses the pixel values from the specified texture (called the displacement map) to perform a displacement of an object.
 * You can use this filter to apply all manor of crazy warping effects
 * Currently the r property of the texture is used to offset the x and the g property of the texture is used to offset the y.
 *
 * @class
 * @extends AbstractFilter
 * @namespace PIXI
 * @param texture {Texture} The texture used for the displacement map * must be power of 2 texture at the moment
 */
function DisplacementFilter(sprite)
{
    var maskMatrix = new core.math.Matrix();
    sprite.renderable = false;

    //TODO move this code out to a frag and vert file.
    core.AbstractFilter.call(this,
        // vertex shader
        [
            'attribute vec2 aVertexPosition;',
            'attribute vec2 aTextureCoord;',
            'attribute vec4 aColor;',

            'uniform mat3 projectionMatrix;',
            'uniform mat3 otherMatrix;',

            'varying vec2 vMapCoord;',
            'varying vec2 vTextureCoord;',
            'varying vec4 vColor;',

            'void main(void)',
            '{',
            '   gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);',
            '   vTextureCoord = aTextureCoord;',
            '   vMapCoord = ( otherMatrix * vec3( aTextureCoord, 1.0)  ).xy;',
            '   vColor = vec4(aColor.rgb * aColor.a, aColor.a);',
            '}'
        ].join('\n'),
        // fragment shader
        [
            'precision lowp float;',

            'varying vec2 vMapCoord;',
            'varying vec2 vTextureCoord;',
            'varying vec4 vColor;',

            'uniform vec2 scale;',

            'uniform sampler2D uSampler;',
            'uniform sampler2D mapSampler;',

            'void main(void)',
            '{',
            '   vec4 original =  texture2D(uSampler, vTextureCoord);',
            '   vec4 map =  texture2D(mapSampler, vMapCoord);',
             '  map -= 0.5;',
            '   map.xy *= scale;',
            '   gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x + map.x, vTextureCoord.y + map.y));',
            '}'
        ].join('\n'),
        // uniforms
        {
            mapSampler:     { type: 'sampler2D', value: sprite.texture },
            otherMatrix:    { type: 'mat3', value: maskMatrix.toArray(true) },
            scale:          { type: 'v2', value: { x: 1, y: 1 } }
        }
    );

    this.maskSprite = sprite;
    this.maskMatrix = maskMatrix;


    this.scale = new PIXI.Point(20,20);

}

DisplacementFilter.prototype = Object.create(core.AbstractFilter.prototype);
DisplacementFilter.prototype.constructor = DisplacementFilter;
module.exports = DisplacementFilter;

DisplacementFilter.prototype.applyFilter = function (renderer, input, output)
{
    var filterManager = renderer.filterManager;

    filterManager.calculateMappedMatrix(input.frame, this.maskSprite, this.maskMatrix);

    this.uniforms.otherMatrix.value = this.maskMatrix.toArray(true);
    this.uniforms.scale.value.x = this.scale.x * (1/input.frame.width);
    this.uniforms.scale.value.y = this.scale.y * (1/input.frame.height);

    var shader = this.getShader(renderer);
     // draw the filter...
    filterManager.applyFilter(shader, input, output);
};


Object.defineProperties(DisplacementFilter.prototype, {
    /**
     * The texture used for the displacement map. Must be power of 2 sized texture.
     *
     * @member {Texture}
     * @memberof DisplacementFilter#
     */
    map: {
        get: function ()
        {
            return this.uniforms.mapSampler.value;
        },
        set: function (value)
        {
            this.uniforms.mapSampler.value = value;

        }
    }
});