diff --git a/src/nodes/WebGL/Blur.js b/src/nodes/WebGL/Blur.js deleted file mode 100644 index 5c31bad..0000000 --- a/src/nodes/WebGL/Blur.js +++ /dev/null @@ -1,82 +0,0 @@ -import WebGL from './WebGl'; - - -export default class Blur extends WebGL { - - constructor() { - super('Blur', { - amount: { - type: 'Number', - default: 0, - }, - }) - } - - _passes() { - const passes = Array(this.in.amount.value) - .fill(null) - .map((x, i) => (gl, program) => this._setParams(gl, program)); - return passes; - } - - get frag() { - return ` - precision mediump float; - - // our texture - uniform sampler2D u_image; - - uniform vec2 u_resolution; - uniform vec2 u_textureSize; - - // the texCoords passed in from the vertex shader. - varying vec2 v_texCoord; - - uniform float kernel[9]; - - void main() { - vec2 onePixel = vec2(1.0, 1.0) / u_textureSize; - - float weight = kernel[0] + - kernel[1] + - kernel[2] + - kernel[3] + - kernel[4] + - kernel[5] + - kernel[6] + - kernel[7] + - kernel[8]; - - vec4 colorSum = - texture2D(u_image, v_texCoord + onePixel * vec2(-1, -1)) * kernel[0] + - texture2D(u_image, v_texCoord + onePixel * vec2(0, -1)) * kernel[1] + - texture2D(u_image, v_texCoord + onePixel * vec2(1, -1)) * kernel[2] + - texture2D(u_image, v_texCoord + onePixel * vec2(-1, 0)) * kernel[3] + - texture2D(u_image, v_texCoord + onePixel * vec2(0, 0)) * kernel[4] + - texture2D(u_image, v_texCoord + onePixel * vec2(1, 0)) * kernel[5] + - texture2D(u_image, v_texCoord + onePixel * vec2(-1, 1)) * kernel[6] + - texture2D(u_image, v_texCoord + onePixel * vec2(0, 1)) * kernel[7] + - texture2D(u_image, v_texCoord + onePixel * vec2(1, 1)) * kernel[8]; - - gl_FragColor = colorSum / weight; - } - ` - } - - get amount() { - return this.in.amount.value; - } - - /** - * - * @param {WebGLRenderingContext} gl - * @param {*} program - */ - _setParams(gl, program) { - gl.uniform1fv(gl.getUniformLocation(program, 'kernel'), [ - 0.045, 0.122, 0.045, - 0.122, 0.332, 0.122, - 0.045, 0.122, 0.045 - ]); - } -} \ No newline at end of file diff --git a/src/nodes/WebGL/Blur.ts b/src/nodes/WebGL/Blur.ts new file mode 100644 index 0000000..d5c92a5 --- /dev/null +++ b/src/nodes/WebGL/Blur.ts @@ -0,0 +1,147 @@ +import WebGL from './WebGl'; +import { + ImageVar, + NumberVar +} from '../io/AbstractIOSet'; + +const inputs = { + image: { + type: 'Image', + } as ImageVar, + radius: { + type: 'Number', + default: 0, + } as NumberVar, + sigma: { + type: 'Number', + default: 0, + } as NumberVar, + passes: { + type: 'Number', + default: 1, + } as NumberVar, +} + + +const outputs = { + image: { + type: 'Image', + } as ImageVar, + width: { + type: 'Number', + } as NumberVar, + height: { + type: 'Number', + } as NumberVar +} + +export default class Blur extends WebGL { + + _lastRadiusValue?: number; + + constructor() { + super('Blur', inputs) + } + + _passes() { + + const passes = Array(Math.max(this.in.passes.value, 0)) + .fill(null) + .flatMap((x, i) => { + return [ + (gl, program) => { + if (i === 0) { + this._setParams(gl, program) + } + this._setDirection(gl, program, [1, 0]) // Horizontal blur + }, + (gl, program) => { + this._setDirection(gl, program, [0, 1]) // Vertical blur + } + ] + }); + return passes; + } + + setup() { + if (this.in.radius.value !== this._lastRadiusValue) { + this.program = undefined; + } + super.setup(); + this._lastRadiusValue = this.in.radius.value; + } + + get frag() { + const RADIUS = Math.ceil(this.in.radius.value); + const KERNEL_SIZE = RADIUS + 1; + return ` + precision mediump float; + + const int RADIUS = ${RADIUS}; + // Our texture + uniform sampler2D u_image; + + uniform vec2 u_resolution; + uniform vec2 u_direction; + uniform vec2 u_textureSize; + + uniform float u_kernel[${KERNEL_SIZE}]; + + // The texCoords passed in from the vertex shader. + varying vec2 v_texCoord; + + void main() { + vec2 onePixel = vec2(1.0, 1.0) / u_textureSize; + + float totalWeight = u_kernel[0]; // Center weight + vec4 colorSum = texture2D(u_image, v_texCoord) * totalWeight; // center pixel + + for (int i = 1; i < ${KERNEL_SIZE}; i++) { + float weight = u_kernel[i]; + totalWeight += weight * 2.0; // Consider both sides of the kernel + vec4 color1 = texture2D(u_image, v_texCoord + onePixel * (u_direction * float(i))); + vec4 color2 = texture2D(u_image, v_texCoord - onePixel * (u_direction * float(i))); + colorSum += (color1 + color2) * weight; + } + + gl_FragColor = colorSum / totalWeight; + gl_FragColor.a = 1.0; + } + ` + } + + gaussian(x, sigma) { + const coeff = 1.0 / (2.0 * Math.PI * sigma * sigma); + const expon = -(x * x) / (2.0 * sigma * sigma); + return coeff * Math.exp(expon); + } + + createGaussianKernel(radius, sigma) { + const kernelSize = radius + 1; + const kernel = new Float32Array(kernelSize); + + for (let i = 0; i < kernelSize; i++) { + kernel[i] = this.gaussian(i, sigma); + } + + return kernel; + } + + + _setDirection(gl: WebGLRenderingContext, program: WebGLProgram, direction: [number, number]) { + gl.uniform2f(gl.getUniformLocation(program, 'u_direction'), direction[0], direction[1]); + } + + /** + * + * @param {WebGLRenderingContext} gl + * @param {*} program + */ + _setParams(gl, program) { + const kernel = this.createGaussianKernel( + this.in.radius.value, + this.in.sigma.value, + ) + gl.uniform1fv(gl.getUniformLocation(program, 'u_kernel'), kernel); + } +} \ No newline at end of file diff --git a/src/nodes/WebGL/WebGl.ts b/src/nodes/WebGL/WebGl.ts index 58f0488..bf771db 100644 --- a/src/nodes/WebGL/WebGl.ts +++ b/src/nodes/WebGL/WebGl.ts @@ -317,15 +317,21 @@ export default class WebGL extends Node 0) { + gl.activeTexture([gl.TEXTURE2, gl.TEXTURE3][i]); + gl.bindTexture(gl.TEXTURE_2D, frameBuffers[(iter-1)%2].texture); + gl.uniform1i(location, i + 2); + } else { + gl.uniform1i(location, i + 2); + gl.activeTexture([gl.TEXTURE2, gl.TEXTURE3][i]); + gl.bindTexture(gl.TEXTURE_2D, tex); + } } } // Draw the rectangle. gl.drawArrays(gl.TRIANGLES, 0, 6); - // gl.bindTexture(gl.TEXTURE_2D, frameBuffer.texture); + gl.bindTexture(gl.TEXTURE_2D, frameBuffer.texture); } const resultCanvas = canvasPool2D.createCanvas(); diff --git a/src/nodes/index.ts b/src/nodes/index.ts index 13c06bb..4f31713 100644 --- a/src/nodes/index.ts +++ b/src/nodes/index.ts @@ -16,7 +16,7 @@ export {default as Channels} from './WebGL/Channels'; export {default as GradientMap} from './WebGL/GradientMap'; export {default as ColorLookupTable} from './WebGL/ColorLookupTable'; export {default as Vignette} from './WebGL/Vignette'; -// export {default as Blur} from './WebGL/Blur'; +export {default as Blur} from './WebGL/Blur'; export {default as Edge} from './WebGL/Edge'; // Math export {default as Numbers} from './Math/Numbers';