functiongenerateGaussianKernel(sigma, kernelSize) { let kernel = newFloat32Array(kernelSize);
// compute kernel elements of Gaussian // do only half(positive side) and mirror to negative side // because Gaussian is even function, symmetric to Y-axis. let center = Math.floor(kernelSize / 2); // center value of n-array(0 ~ n-1)
let result = 0; let sum = 0; if(sigma == 0) { kernel.fill(0); kernel[center] = 1.0; } else { constSS2 = sigma * sigma * 2; kernel[center] = 1; sum = 1; for(let x = 1; x <= center; ++x) { // dividing (sqrt(2*PI)*sigma) is not needed because normalizing result later result = Math.exp(-(x*x)/SS2); kernel[center+x] = kernel[center-x] = result; sum += result; sum += result; }
// normalize kernel // make sum of all elements in kernel to 1 for(let i = 0; i <= center; ++i) kernel[center+i] = kernel[center-i] /= sum; } return kernel; }
// Gaussian Blur Fragment Shader // constants constint MAX_KERNEL = 21; // max half kernel size including the center constfloat ZERO = 0.0; constfloat ONE = 1.0;
// uniforms uniformfloat kernel[MAX_KERNEL]; // half gaussian kernel from center uniformvec2imageSize; uniformvec2 direction; // horizontal=(1,0) or vertical=(0,1) uniformsampler2D map0; // input image
// input varying variables varyingvec2 texCoord0;
void main(void) { // compute the center first vec3 color = texture2D(map0, texCoord0).rgb * kernel[0]; vec2offset; vec2 texelSize = 1.0f / imageSize;
// compute with other kernel elements for(int i = 1; i < MAX_KERNEL; ++i) { offset = direction * float(i) * texelSize; color += texture2D(map0, texCoord0 + offset).rgb * kernel[i]; // positive side color += texture2D(map0, texCoord0 - offset).rgb * kernel[i]; // negative side }
// Gaussian Blur Fragment Shader with texture filtering // constants constint MAX_KERNEL = 21; // max half kernel size including the center constfloat ZERO = 0.0; constfloat ONE = 1.0;
// uniforms uniformfloat kernel[MAX_KERNEL]; // half gaussian kernel from center uniformfloat imageDimension; uniformvec2 direction; // horizontal=(1,0) or vertical=(0,1) uniformsampler2D map0; // input image
// input varying variables varyingvec2 texCoord0;
void main(void) { // compute the center texel first vec3 color = texture2D(map0, texCoord0).rgb * kernel[0]; vec2offset;
// optimize using linear texture filtering (with half texels) float k; // interpolated kernel, H = H1 + H2 float t; // interpolated alpha, t = H2 / H for(int i = 1; i < MAX_KERNEL; i += 2) { k = kernel[i] + kernel[i+1]; t = kernel[i+1] / k; offset = direction * (float(i) + t) / imageDimension; color += texture2D(map0, texCoord0 + offset).rgb * k; color += texture2D(map0, texCoord0 - offset).rgb * k; }