const AbstractFilter = require('../../core/renderers/webgl/filters/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
* @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,
// vertex shader
null,
// fragment shader
require('./convolution.frag'),
// custom uniforms
{
matrix: { type: '1fv', value: new Float32Array(matrix) },
texelSize: { type: 'v2', value: { x: 1 / width, y: 1 / height } },
}
);
}
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 filters.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 filters.ConvolutionFilter#
*/
width: {
get: function() {
return 1 / this.uniforms.texelSize.value.x;
},
set: function(value) {
this.uniforms.texelSize.value.x = 1 / value;
},
},
/**
* Height of the object you are transforming
*
* @member {number}
* @memberof filters.ConvolutionFilter#
*/
height: {
get: function() {
return 1 / this.uniforms.texelSize.value.y;
},
set: function(value) {
this.uniforms.texelSize.value.y = 1 / value;
},
},
});