I am trying to get this working with Codea:
https://github.com/vincent23/love2d-experiments/blob/master/metaball/main.lua
I have recorded a video but the image is flipped, dont know why exactly xD
Here is the Main.lua for Codea
balls    = {}
v        = {}
x        = 0
y        = 0
radius   = 66
width    = WIDTH-radius
height   = HEIGHT-radius
paused   = false
time     = 0
strobo   = false
m        = nil
--[[ 
original source code , love2d version:
https://github.com/vincent23/love2d-experiments/blob/master/metaball/main.lua
]]--
displayMode(STANDARD)
function setup()
    parameter.number("schwelle",0.002, 2.0, 0.002)
    parameter.boolean("drawMesh",false)
    local i = 0
    for i=1,40 do
        balls[i]    = {math.random(0,width), math.random(0,height)}
        local v_ges = math.random(200,400)
        local v_x   = math.random(0,v_ges)
        local v_y   = math.sqrt(math.pow(v_ges,2) - math.pow(v_x,2))
        v[i]        = {v_x, v_y}
    end
    
    m = mesh()
    m.texture = "Cargo Bot:Codea Icon"
    m.shader  = shader("Documents:MetaBall")
    rIdx = m:addRect(0, 0, 0, 0)
    m:setRectColor(i, 127,0,0)
    m:setRect(rIdx, WIDTH/2, HEIGHT/2, WIDTH, HEIGHT)
    m.shader.width    = width
    m.shader.height   = height
    m.shader.time     = time
    m.shader.schwelle = schwelle
end
function draw()
    background(0)
    strokeWidth(2)
    fill(17, 120, 223, 255)
    stroke(17, 120, 223, 255)
    local dt = DeltaTime
    time = time + dt
    if paused then
        return
    end
    for i=1,#balls do
        for j=1,#balls do
            if i ~= j then
                local left, right
                local bottom, top
                if balls[i][1] < balls[j][1] then
                    left = i
                    right = j
                else
                    left = j
                    right = i
                end
                if balls[i][2] < balls[j][2] then
                    bottom = i
                    top = j
                else
                    bottom = j
                    top = i
                end
                local x = balls[right][1]-balls[left][1]
                local y = balls[right][2]-balls[left][2]
                local r = math.sqrt(math.pow(x,2) + math.pow(y,2))
                local f = 200000/math.pow(r,2) * dt
                local fx = x/r*f
                local fy = y/r*f
                balls[left][1] = balls[left][1] - fx
                balls[right][1] = balls[right][1] + fx
                balls[left][2] = balls[left][2] - fy
                balls[right][2] = balls[right][2] + fy
            end
        end
    end
    for i=1,#balls do
        balls[i][1] = balls[i][1] + v[i][1] * dt
        if (balls[i][1] < 10 and v[i][1] < 0) or (balls[i][1] >= width -10 and v[i][1] > 0) then
            v[i][1] = v[i][1] * (-1)
        end
        balls[i][2] = balls[i][2] + v[i][2] * dt
        if (balls[i][2] < 10 and v[i][2] < 0) or (balls[i][2] >= height-10 and v[i][2] > 0) then
            v[i][2] = v[i][2] * (-1)
        end
        if not drawMesh then
            ellipse(balls[i][1],balls[i][2],radius)
        end
    end
    if drawMesh then
        --local cw,ch = spriteSize(m.texture)
        --m:setRect(rIdx, WIDTH/2, HEIGHT/2, cw, ch) -- uncomment if texture size changes
    
        -- Configure out custom uniforms for the shader
        if strobo then
            m.shader.time = time --ElapsedTime
        end
        --m.shader.schwelle = schwelle
        --m.shader.width = cw
        --m.shader.height = ch
        m.shader.balls = balls
        
        -- Draw the mesh
        m:draw()
    end
end
function touched(touch)
    if touch.state == BEGAN then
        paused = not paused
        print("paused:",paused)
    end
end
This is the vertex program for the metaballs shader:
//
// A metaballs shader
//
//This is the current model * view * projection matrix
// Codea sets it automatically
uniform mat4 modelViewProjection;
uniform float width;
uniform float height;
uniform float schwelle;
uniform vec2 balls[40];
uniform float time;
//This is the current mesh vertex position, color and tex coord
// Set automatically
attribute vec4 position;
attribute vec4 color;
attribute vec2 texCoord;
//This is an output variable that will be passed to the fragment shader
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
varying highp vec4 bColor;
float metaball(vec2 center, vec2 point) {
    vec2 v = point-center;
    return 1.0/dot(v, v);
}
vec4 effect(
    vec4 color, vec2 tex_c,vec2 coord
) {
        float val = 0.0;
        for (int i =0; i<40; i++) {
            val = val + metaball(balls[i],coord);
        }
        
    vec4 bar;
        
    if (val < schwelle) {
            val = val / schwelle;
            bar = vec4(
                0.8*(1.0-coord.x/width),
                0.8*(1.0-coord.y/height),
                0.3*val,
                1.0
            );
        }
        else {
            bar = vec4(
                0.8*coord.x/width,
                0.8*coord.y/height,
                0.0,1.0
            );
        }
        float foo = mod(time,1.0);
        if (foo < 0.1) {
         return bar + vec4(vec3(foo*3.14*50.0), 1.0);
        }   
    return bar;
}
void main()
{
    //Pass the mesh color to the fragment shader
    vColor    = color;
    vTexCoord = vec2(texCoord.x, 1.0 - texCoord.y);
    //Pass the balls effect color to the fragment
    bColor    = effect(color, texCoord, vTexCoord);
    //Multiply the vertex position by our combined transform
    gl_Position = modelViewProjection * position;
    
}
and here it is the fragment program:
//
// A metaballs fragment shader
//
//This represents the current texture on the mesh
uniform lowp sampler2D texture;
//The interpolated vertex color for this fragment
varying lowp vec4 vColor;
//The interpolated texture coordinate for this fragment
varying highp vec2 vTexCoord;
//balls effect
varying highp vec4 bColor;
void main()
{
    //Sample the texture at the interpolated coordinate
    lowp vec4 col = texture2D( texture, vTexCoord );
    //Set the output color to the texture color
    gl_FragColor = bColor+col;
    
}
Hope you smart people know How to fix this 
