Smudging an image

Hey guys, I’m trying to smudge an image by copying a 10 pixel image and moving it pixel by pixel and drawing it to the screen, I’ve taken advantage of the blur shader to make it more smudge like, but anything I draw with low opacity (e.g. the outer of the blur) becomes darker, instead of mixing. I was going to take advantage of the color.blend function and use img:get and img:set to blend these pixels, but the way I’m using seems to be more efficient. Here’s the code, how can I stop it from darkening and instead just blend the pixels with the background of the copied 10pixel image?

local spos = (smudgepos-vec2(td.x,td.y)):normalize()*-1
            smudgepos = smudgepos+spos 
            setContext(screen)
                local m = mesh()
                local size = 15-smudgepos:dist(prev)/3
                local r = m:addRect(smudgepos.x,smudgepos.y,size,size)
                m.texture = smudgeimg
                m.shader = shader("Filters:Blur")
                m.shader.conPixel = vec2(1/size,1/size)
                m.shader.conWeight = 1/9
                m:setColors(255,255,255,255)
                m:draw()
            setContext()

I suspect that the correct choice of blend mode will help here. If you post a full example, I’d be happy to experiment.

@Andrew_Stacey thanks, the above code relates to the moving state in the touch function, ill just extract it from my project and put it in a little example, Ill paste the code in 2 mins.

@Andrew_Stacey here you go:


--# Main
function setup()
    smudgeimg = nil
    smudgepos = nil
    prev = nil
    smudgem,smudger = nil
    screen = image(WIDTH,HEIGHT)
    setContext(screen)
    pushStyle()
        background(0,0,0,0)
        fill(255,0,0)
        rect(200,300,300,400)
        fill(0,255,0)
        rect(300,100,400,200)
        fill(0,0,255)
        rect(100,500,500,200)
    popStyle()
    setContext()
    
end
 
function imgcopycircle(img,x,y,r)
    local imgc = img:copy(x-r/2,y-r/2,r,r)
    for tx = 1,r do
        for ty = 1,r do
            if vec2(r/2,r/2):dist(vec2(tx,ty)) > r/2 then
                imgc:set(tx,ty,0,0,0,0)
            end
        end
    end
    return imgc
end

function draw()    
    background(255)
    sprite(screen,WIDTH/2,HEIGHT/2)   
end
              
function touched(t) 
    local td = vec2(t.x,t.y)                       
    if t.state == BEGAN then
        prev = vec2(td.x,td.y)
        smudgeimg = imgcopycircle(screen,td.x,td.y,10)
        smudgepos = prev
        smudgem = mesh()
        local size = 15
        smudger = smudgem:addRect(smudgepos.x,smudgepos.y,size,size)
        smudgem.texture = smudgeimg
        smudgem.shader = shader("Filters:Blur")
        smudgem.shader.conPixel = vec2(1/10,1/10)
        smudgem.shader.conWeight = 1/9
        smudgem:setColors(255,255,255,255)
    end
    if t.state == MOVING and smudgepos then
        local spos = (smudgepos-vec2(td.x,td.y)):normalize()*-1
        smudgepos = smudgepos+spos 
        setContext(screen)
            local size = 15-smudgepos:dist(prev)/3
            smudgem:setRect(smudger,smudgepos.x,smudgepos.y,size,size)
            smudgem:draw()
        setContext()
        smudgeimg = imgcopycircle(screen,smudgepos.x,smudgepos.y,10)
        smudgem.texture = smudgeimg
        if 10-smudgepos:dist(prev)/3<0 then prev = nil end
        --prev = vec2(td.x,td.y)
        --smudgeimg = screen:copy(smudgepos.x-5,smudgepos.y-5,10,10)
    end
    if t.state == ENDED and prev or prev == nil then
        prev = nil
        smudgeimg = nil
        smudgepos = nil
        smudgem = nil
        smudger = nil
    end
end

Works a bit better zoomed in but I’m stuck in the middle of a video game so I didnt put it in.