Edit in JSFiddle

var scene = document.getElementById("scene");
var gl = scene.getContext("webgl");

var createProgram = function (vsh, fsh) {
    var program = gl.createProgram();
    gl.attachShader(program, vsh);
    gl.attachShader(program, fsh);
    gl.linkProgram(program);

    var status = gl.getProgramParameter(program, gl.LINK_STATUS);
    if (!status) {
        var error = gl.getProgramInfoLog(program);
        console.error("Failed to link shader program: " + error);
        gl.deleteProgram(program);
        gl.deleteShader(vsh);
        gl.deleteShader(fsh);
        return null;
    }

    return program;
};

var createShader = function (type, src) {
    var shader = gl.createShader(type);
    gl.shaderSource(shader, src);
    gl.compileShader(shader);

    var status = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
    if (!status) {
        var error = gl.getShaderInfoLog(shader);
        console.error("Failed to compile shader: " + error);
        gl.deleteShader(shader);
        return null;
    }

    return shader;
};

var createTexture = function (width, height) {
    var tex = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, tex);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

    return tex;
};

var line_vsh_src = "" +
    "attribute vec2 a_pos;" +
    "attribute vec4 a_color;" +
    "varying vec4 v_color;" +
    "void main(){" +
    "   gl_Position = vec4(a_pos, 0.0, 1.0);" +
    "   v_color = a_color;" +
    "}";

var line_fsh_src = "" +
    "#ifdef GL_ES\n" +
    "precision mediump float;\n" +
    "#endif\n" +
    "varying vec4 v_color;" +
    "void main(){" +
    "   gl_FragColor = v_color;" +
    "}";

var line_vsh = createShader(gl.VERTEX_SHADER, line_vsh_src);
var line_fsh = createShader(gl.FRAGMENT_SHADER, line_fsh_src);
var line_program = createProgram(line_vsh, line_fsh);

gl.useProgram(line_program);
var line_a_pos = gl.getAttribLocation(line_program, "a_pos");
var line_a_color = gl.getAttribLocation(line_program, "a_color");

var canvas_vsh_src = "" +
    "attribute vec2 a_pos;" +
    "attribute vec2 a_texcoord;" +
    "varying vec2 v_texcoord;" +
    "void main(){" +
    "   gl_Position = vec4(a_pos, 0.0, 1.0);" +
    "   v_texcoord = a_texcoord;" +
    "}";

var canvas_fsh_src = "" +
    "#ifdef GL_ES\n" +
    "precision mediump float;\n" +
    "#endif\n" +
    "uniform sampler2D u_tex;" +
    "varying vec2 v_texcoord;" +
    "void main(){" +
    "   gl_FragColor = texture2D(u_tex, v_texcoord);" +
    "}";

var canvas_vsh = createShader(gl.VERTEX_SHADER, canvas_vsh_src);
var canvas_fsh = createShader(gl.FRAGMENT_SHADER, canvas_fsh_src);
var canvas_program = createProgram(canvas_vsh, canvas_fsh);

gl.useProgram(canvas_program);
var canvas_a_pos = gl.getAttribLocation(canvas_program, "a_pos");
var canvas_a_texcoord = gl.getAttribLocation(canvas_program, "a_texcoord");
var canvas_u_tex = gl.getUniformLocation(canvas_program, "u_tex");

var canvas_vertices = new Float32Array([
    -1, -1, 0, 0, // BL
    1, -1, 1, 0, // BR
    1, 1, 1, 1, // TR
    -1, 1, 0, 1 // TL
]);

var canvas_indices = new Uint8Array([
    0, 1, 2, 2, 3, 0
]);

var canvas_vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, canvas_vbo);
gl.bufferData(gl.ARRAY_BUFFER, canvas_vertices, gl.STATIC_DRAW);

var canvas_ebo = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, canvas_ebo);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, canvas_indices, gl.STATIC_DRAW);

var line_blur_fsh_src = "" +
    "#ifdef GL_ES\n" +
    "precision mediump float;\n" +
    "#endif\n" +
    "uniform sampler2D u_tex;" +
    "uniform vec2 u_offset;" +
    "varying vec2 v_texcoord;" +
    "vec3 GaussianBlur(sampler2D tex, vec2 centreUV, vec2 pixelOffset) {" +
    "   vec3 colOut = vec3(0, 0, 0);" +
    "   const int stepCount = 2;" +
    "   float gWeights[stepCount];" +
    "   gWeights[0] = 0.64908;" +
    "   gWeights[1] = 0.15092;" +
    "   float gOffsets[stepCount];" +
    "   gOffsets[0] = 0.53805;" +
    "   gOffsets[1] = 2.06278;" +
    "   for (int i = 0; i < stepCount; i++) {" +
    "       vec2 texCoordOffset = gOffsets[i] * pixelOffset;" +
    "       vec3 col = texture2D(tex, centreUV + texCoordOffset).xyz +" +
    "       texture2D(tex, centreUV - texCoordOffset).xyz;" +
    "       colOut += gWeights[i] * col;" +
    "   }" +
    "   return colOut;" +
    "}" +
    "void main(){" +
    "   gl_FragColor = /*texture2D(u_tex, v_texcoord);*/vec4(GaussianBlur(u_tex, v_texcoord, u_offset), 1.0);" +
    "}";

var line_blur_fsh = createShader(gl.FRAGMENT_SHADER, line_blur_fsh_src);
var line_blur_program = createProgram(canvas_vsh, line_blur_fsh);

gl.useProgram(line_blur_program);
var line_blur_a_pos = gl.getAttribLocation(line_blur_program, "a_pos");
var line_blur_a_texcoord = gl.getAttribLocation(line_blur_program, "a_texcoord");
var line_blur_u_tex = gl.getUniformLocation(line_blur_program, "u_tex");
var line_blur_u_offset = gl.getUniformLocation(line_blur_program, "u_offset");

var line_tex_size = 256;
var blur_tex_size = 64;

var line_tex = createTexture(line_tex_size, line_tex_size);
var line_blur_h_tex = createTexture(blur_tex_size, blur_tex_size);
var line_blur_tex = createTexture(blur_tex_size, blur_tex_size);

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, line_tex);

var line_framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, line_framebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, line_tex, 0);

gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, line_blur_h_tex);

gl.activeTexture(gl.TEXTURE2);
gl.bindTexture(gl.TEXTURE_2D, line_blur_tex);

var line_blur_framebuffer = gl.createFramebuffer();

var line_points = [
], count = 0, max = 15;

var line_vbo = gl.createBuffer();

var map = function (v, l, h, f, t) {
    return (v - l) / (h - l) * (t - f) + f;
};

scene.onmousemove = function (e) {
    var x = map(e.offsetX, 0, 512, -1, 1);
    var y = map(e.offsetY, 512, 0, -1, 1);

    line_points.push(x, y, Math.random(), Math.random(), Math.random(), 1);

    if (count < max) {
        count++;
    } else {
        line_points.shift();
        line_points.shift();
        line_points.shift();
        line_points.shift();
        line_points.shift();
        line_points.shift();
    }
};

gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.enable(gl.BLEND);
gl.lineWidth(1.5);

requestAnimationFrame(function loop() {

    // draw lines on line framebuffer
    gl.bindFramebuffer(gl.FRAMEBUFFER, line_framebuffer);
    gl.clear(gl.COLOR_BUFFER_BIT);

    var line_points_float = new Float32Array(line_points);

    gl.bindBuffer(gl.ARRAY_BUFFER, line_vbo);
    gl.bufferData(gl.ARRAY_BUFFER, line_points_float, gl.DYNAMIC_DRAW);

    gl.vertexAttribPointer(line_a_pos, 2, gl.FLOAT, false, line_points_float.BYTES_PER_ELEMENT * 6, 0);
    gl.enableVertexAttribArray(line_a_pos);

    gl.vertexAttribPointer(line_a_color, 4, gl.FLOAT, false, line_points_float.BYTES_PER_ELEMENT * 6, line_points_float.BYTES_PER_ELEMENT * 2);
    gl.enableVertexAttribArray(line_a_color);

    gl.viewport(0, 0, line_tex_size, line_tex_size);

    gl.useProgram(line_program);
    gl.drawArrays(gl.LINE_STRIP, 0, line_points_float.length / 6);

    // draw blur lines on line blur framebuffer
    gl.bindFramebuffer(gl.FRAMEBUFFER, line_blur_framebuffer);

    gl.bindBuffer(gl.ARRAY_BUFFER, canvas_vbo);

    gl.vertexAttribPointer(line_blur_a_pos, 2, gl.FLOAT, false, canvas_vertices.BYTES_PER_ELEMENT * 4, 0);
    gl.enableVertexAttribArray(line_blur_a_pos);

    gl.vertexAttribPointer(line_blur_a_texcoord, 2, gl.FLOAT, false, canvas_vertices.BYTES_PER_ELEMENT * 4, canvas_vertices.BYTES_PER_ELEMENT * 2);
    gl.enableVertexAttribArray(line_blur_a_texcoord);

    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, canvas_ebo);

    gl.viewport(0, 0, blur_tex_size, blur_tex_size);

    gl.useProgram(line_blur_program);

    // draw h-blur lines on line blur framebuffer
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, line_blur_h_tex, 0);
    gl.uniform1i(line_blur_u_tex, 0);
    gl.uniform2f(line_blur_u_offset, 0.5 / blur_tex_size, 0);
    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);

    // draw v-blur lines on line blur framebuffer
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, line_blur_tex, 0);
    gl.uniform1i(line_blur_u_tex, 1);
    gl.uniform2f(line_blur_u_offset, 0, 0.5 / blur_tex_size);
    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);

    // draw canvas
    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    gl.clear(gl.COLOR_BUFFER_BIT);

    gl.bindBuffer(gl.ARRAY_BUFFER, canvas_vbo);

    gl.vertexAttribPointer(canvas_a_pos, 2, gl.FLOAT, false, canvas_vertices.BYTES_PER_ELEMENT * 4, 0);
    gl.enableVertexAttribArray(canvas_a_pos);

    gl.vertexAttribPointer(canvas_a_texcoord, 2, gl.FLOAT, false, canvas_vertices.BYTES_PER_ELEMENT * 4, canvas_vertices.BYTES_PER_ELEMENT * 2);
    gl.enableVertexAttribArray(canvas_a_texcoord);

    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, canvas_ebo);

    gl.viewport(0, 0, 512, 512);

    gl.useProgram(canvas_program);

    gl.uniform1i(canvas_u_tex, 0);
    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);

    gl.blendFunc(gl.ONE, gl.ONE);
    gl.uniform1i(canvas_u_tex, 2);
    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
    gl.blendFunc(gl.ONE, gl.ZERO);

    requestAnimationFrame(loop);
});