const AbstractFilter = require('../../core/renderers/webgl/filters/AbstractFilter');
const Vector = require('engine/Vector');
const { Matrix } = require('../../core/math');
/**
* 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
* @param sprite {Sprite} the sprite used for the displacement map. (make sure its added to the scene!)
*/
function DisplacementFilter(sprite, scale) {
var maskMatrix = new Matrix();
sprite.renderable = false;
AbstractFilter.call(this,
// vertex shader
require('./displacement.vert'),
// fragment shader
require('./displacement.frag'),
// 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;
if (scale === null || scale === undefined) {
scale = 20;
}
this.scale = Vector.create(scale, scale);
}
DisplacementFilter.prototype = Object.create(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 filters.DisplacementFilter#
*/
map: {
get: function() {
return this.uniforms.mapSampler.value;
},
set: function(value) {
this.uniforms.mapSampler.value = value;
},
},
});