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; } } });