var AbstractFilter = require('./AbstractFilter');
/**
* The ConvolutionFilter class applies a matrix convolution filter effect.
* A convolution combines pixels in the input image with neighboring pixels to produce a new image.
* A wide variety of image effects can be achieved through convolutions, including blurring, edge
* detection, sharpening, embossing, and beveling. The matrix should be specified as a 9 point Array.
* See http://docs.gimp.org/en/plug-in-convmatrix.html for more info.
*
* @class
* @extends AbstractFilter
* @namespace PIXI
* @param matrix {number[]} An array of values used for matrix transformation. Specified as a 9 point Array.
* @param width {number} Width of the object you are transforming
* @param height {number} Height of the object you are transforming
*/
function ConvolutionFilter(matrix, width, height) {
AbstractFilter.call(this);
// set the uniforms
this.uniforms = {
matrix: { type: '1fv', value: new Float32Array(matrix) },
texelSizeX: { type: '1f', value: 1 / width },
texelSizeY: { type: '1f', value: 1 / height }
};
this.fragmentSrc = [
'precision mediump float;',
'varying mediump vec2 vTextureCoord;',
'uniform sampler2D texture;',
'uniform float texelSizeX;',
'uniform float texelSizeY;',
'uniform float matrix[9];',
'vec2 px = vec2(texelSizeX, texelSizeY);',
'void main(void) {',
' vec4 c11 = texture2D(texture, vTextureCoord - px);', // top left
' vec4 c12 = texture2D(texture, vec2(vTextureCoord.x, vTextureCoord.y - px.y));', // top center
' vec4 c13 = texture2D(texture, vec2(vTextureCoord.x + px.x, vTextureCoord.y - px.y));', // top right
' vec4 c21 = texture2D(texture, vec2(vTextureCoord.x - px.x, vTextureCoord.y) );', // mid left
' vec4 c22 = texture2D(texture, vTextureCoord);', // mid center
' vec4 c23 = texture2D(texture, vec2(vTextureCoord.x + px.x, vTextureCoord.y) );', // mid right
' vec4 c31 = texture2D(texture, vec2(vTextureCoord.x - px.x, vTextureCoord.y + px.y) );', // bottom left
' vec4 c32 = texture2D(texture, vec2(vTextureCoord.x, vTextureCoord.y + px.y) );', // bottom center
' vec4 c33 = texture2D(texture, vTextureCoord + px );', // bottom right
' gl_FragColor = ',
' c11 * matrix[0] + c12 * matrix[1] + c22 * matrix[2] +',
' c21 * matrix[3] + c22 * matrix[4] + c23 * matrix[5] +',
' c31 * matrix[6] + c32 * matrix[7] + c33 * matrix[8];',
' gl_FragColor.a = c22.a;',
'}'
];
};
ConvolutionFilter.prototype = Object.create(AbstractFilter.prototype);
ConvolutionFilter.prototype.constructor = ConvolutionFilter;
module.exports = ConvolutionFilter;
Object.defineProperties(ConvolutionFilter.prototype, {
/**
* An array of values used for matrix transformation. Specified as a 9 point Array.
*
* @member {number[]}
* @memberof ConvolutionFilter#
*/
matrix: {
get: function () {
return this.uniforms.matrix.value;
},
set: function (value) {
this.uniforms.matrix.value = new Float32Array(value);
}
},
/**
* Width of the object you are transforming
*
* @member {number}
* @memberof ConvolutionFilter#
*/
width: {
get: function () {
return this.uniforms.texelSizeX.value;
},
set: function (value) {
this.uniforms.texelSizeX.value = 1/value;
}
},
/**
* Height of the object you are transforming
*
* @member {number}
* @memberof ConvolutionFilter#
*/
height: {
get: function () {
return this.uniforms.texelSizeY.value;
},
set: function (value) {
this.uniforms.texelSizeY.value = 1/value;
}
}
});