Not sure if this will do.
Code: Select all
local shader = [[
extern number w, h;
extern Image mosaic_image;
vec4 effect(vec4 colour, Image img, vec2 imgpos, vec2 scrpos)
{
vec4 pix = Texel(img, imgpos) * colour;
vec4 mosaic = Texel(mosaic_image, imgpos*vec2(w,h)) * colour;
// Apply soft light (lerp between multiply and screen, modulated by bottom)
pix.rgb = mix(pix.rgb * mosaic.rgb, // multiply
(vec3(1.) - (vec3(1.) - mosaic.rgb) * (vec3(1.) - pix.rgb)), // screen
pix.rgb // bottom layer modulates
);
pix.a = min(pix.a, mosaic.a);
return pix;
}
]]
local img
function love.load(arg)
img = love.graphics.newImage(arg[1])
img:setFilter("linear", "nearest")
local mosaic = love.graphics.newImage('mosaic-base.png')
mosaic:setWrap("repeat")
mosaic:setFilter("linear", "nearest")
shader = love.graphics.newShader(shader)
shader:send('mosaic_image', mosaic)
end
function love.draw()
love.graphics.setShader(shader)
shader:send("w", img:getWidth())
shader:send("h", img:getHeight())
love.graphics.draw(img, 0, 0, 0, 3)
love.graphics.setShader()
end
function love.keypressed(k) return k == "escape" and love.event.quit() end
It's a simple soft-light blending shader. The shader needs to know the dimensions of the image you're drawing, so you need to pass them in. The zoom needs to be a multiple of 3, because the basic mosaic tile is 3x3. If you make a tile of a different size, the zoom needs to be a multiple of that size.
The above example needs the image to load as a parameter, e.g. love . <image to draw>.png
Edit: Forgot to attach the mosaic image.