UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

59 lines (42 loc) 1.78 kB
import LineBuilder from "../../../../../core/codegen/LineBuilder.js"; import { gaussian } from "../../../../../core/math/gaussian.js"; /** * Pre-build kernel internally, no branches in convolution code, everything is inlined * @param {number} samples * @param {number} distance * @returns {string} */ export function makeGaussianBlurShader({ samples = 5, distance = samples }) { const kernel_size = samples * samples; const sigma = (kernel_size - 1) / 6; const lb = new LineBuilder(); lb.add('uniform vec2 resolution;'); lb.add('uniform sampler2D tDiffuse;'); lb.add('uniform sampler2D tMask;'); lb.add('varying vec2 vUv;'); const half_samples = (samples / 2) | 0; lb.add('void main(){'); lb.indent(); lb.add('if( texture2D(tMask, vUv).x < 1.0){ gl_FragColor = vec4(0.0); return; }'); lb.add('vec2 pixel_uv = 1.0 / resolution;') lb.add('vec4 accumulator;') const scale_x = (distance / samples); const scale_y = (distance / samples); // prepare samples let total_value = 0; for (let iy = 0; iy < samples; iy++) { const fy = gaussian(sigma, iy - half_samples); const offset_y = (iy - half_samples) * scale_y; for (let ix = 0; ix < samples; ix++) { const fx = gaussian(sigma, ix - half_samples); const offset_x = (ix - half_samples) * scale_x; const value = fx * fy; total_value += value; lb.add(`accumulator += texture2D(tDiffuse, vUv + vec2(float(${offset_x}), float(${offset_y})) * pixel_uv) * float(${value});`); } } lb.add(`gl_FragColor = accumulator / ${total_value};`); lb.dedent(); lb.add('}'); return lb.build(); }