Overlay

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
tobiasvl
Prole
Posts: 29
Joined: Mon Oct 01, 2018 4:58 pm
Location: Norway
Contact:

Overlay

Post by tobiasvl »

Hey, I don't really understand blend modes, and am wondering if this is possible.

I'm drawing a monochrome white and transparent black canvas, and I want to overlay that with a colored image. The transparent black parts of the canvas should stay transparent black, but the white parts should take on the colors of the overlay. Is this possible?

The overlay is currently a PNG image that's transparent wherever I don't want the color affected, and the other parts are solid colors. I can change that, of course.
User avatar
pgimeno
Party member
Posts: 3656
Joined: Sun Oct 18, 2015 2:58 pm

Re: Overlay

Post by pgimeno »

I'm not sure I'm understanding, but doesn't "multiply", "premultiplied" do this?
tobiasvl
Prole
Posts: 29
Joined: Mon Oct 01, 2018 4:58 pm
Location: Norway
Contact:

Re: Overlay

Post by tobiasvl »

Maybe? I have no idea. Where would I set that blend mode, before drawing the canvas or the overlay? I guess my main problem is that I have no idea how blend modes work, lol. None of the ways I try work, but I'm just doing it blindly here. Are there any good tutorials on blending?
User avatar
pgimeno
Party member
Posts: 3656
Joined: Sun Oct 18, 2015 2:58 pm

Re: Overlay

Post by pgimeno »

If I understood what you're after I would be able to give you better advice.

For colours, white (or full intensity of a given component) counts as 1.0, black counts as 0.0; for alpha, fully opaque counts as 1.0 and transparent as 0.0. That's the value that gets multiplied by the given component.

This means that with multiply blend mode, everything transparent will remain transparent (per the alpha multiplication) and everything of a certain colour will remain that colour when applied to a white background (per the multiplication of the colour components by 1).

But if the image you're drawing on the white circle has alpha, that alpha will result in the trimming of the other alpha when multiplied, which does not seem what you want. So, this method can be used on an image which has a white background.

But I don't know what you have exactly and what you want exactly.
tobiasvl
Prole
Posts: 29
Joined: Mon Oct 01, 2018 4:58 pm
Location: Norway
Contact:

Re: Overlay

Post by tobiasvl »

Yeah, I think I confused myself too. Sorry.

Basically, I want to combine two images/canvases. One is monochrome black and white, and the other is a background that "tints" the white parts of the first one. But then I want to overlay that combined canvas on top of another background again, where the black parts are now transparent and show the final background.

I didn't really explain that final part, sorry about that, I just said the first canvas had a "transparent black" background.

See this image for a simplified visualization:
love2d-overlay.png
love2d-overlay.png (3.62 KiB) Viewed 13318 times
User avatar
FloatingBanana
Prole
Posts: 22
Joined: Sat Mar 02, 2019 4:57 pm
Contact:

Re: Overlay

Post by FloatingBanana »

Maybe love.graphics.stencil can do it.

Code: Select all

if anyMistake(self.english) then
    print("Sorry, english is not my first language")
end
tobiasvl
Prole
Posts: 29
Joined: Mon Oct 01, 2018 4:58 pm
Location: Norway
Contact:

Re: Overlay

Post by tobiasvl »

Thank you! Stencil looks exactly like what I want.
User avatar
pgimeno
Party member
Posts: 3656
Joined: Sun Oct 18, 2015 2:58 pm

Re: Overlay

Post by pgimeno »

OK, so I assume that the black and white image is a mask, the blue image is the background, and the red image is the one you want to draw over the background using the mask.

This works for me:

Code: Select all

local bg = love.graphics.newImage('mountain-and-lake-landscape-800x600.jpg')
local fg = love.graphics.newImage('image1.jpg')
local mask = love.graphics.newImage('Circle.png')
local canvas = love.graphics.newCanvas()

local x, y
local a = 0

-- In the Circle.png image, the circle is at 570, 370 with a size of 460x460.
function love.update(dt)
  a = a + dt
  x = (math.sin(a * 1.5) + 1) / 2 * (love.graphics.getWidth() - 460) - 570
  y = (math.sin(a * 2) + 1) / 2 * (love.graphics.getHeight() - 460) - 370
end

function love.draw()
  love.graphics.setCanvas(canvas)
  love.graphics.setBlendMode('replace', 'premultiplied')
  love.graphics.draw(fg)
  love.graphics.setBlendMode('multiply', 'premultiplied')
  love.graphics.draw(mask)
  love.graphics.setCanvas()

  love.graphics.setBlendMode('replace', 'premultiplied')
  love.graphics.draw(bg)
  love.graphics.setBlendMode('alpha', 'alphamultiply')
  love.graphics.draw(canvas)
end
See attached demo.

The stencil has the problem that the borders have no antialiasing.
Attachments
overlay.love
(198.54 KiB) Downloaded 352 times
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Overlay

Post by grump »

Another solution using a shader:

Code: Select all

local lg = love.graphics
local red, blue, mask = lg.newCanvas(), lg.newCanvas(), lg.newCanvas()
red:renderTo(function() lg.clear(1, .2, .2) end)
blue:renderTo(function() lg.clear(.2, .2, 1) end)
mask:renderTo(function() lg.circle('fill', 200, 200, 100) end)

local maskShader = lg.newShader([[
	uniform Image imageA, imageB;

	vec4 effect(vec4 color, Image mask, vec2 uv, vec2 fc) {
		return color * mix(Texel(imageB, uv), Texel(imageA, uv), Texel(mask, uv));
	}
]])

function love.draw()
	lg.setBlendMode('alpha', 'premultiplied')
	lg.setShader(maskShader)
	maskShader:send('imageA', red)
	maskShader:send('imageB', blue)
	lg.draw(mask)
end
tobiasvl
Prole
Posts: 29
Joined: Mon Oct 01, 2018 4:58 pm
Location: Norway
Contact:

Re: Overlay

Post by tobiasvl »

Thanks a lot, that blend example helped. The shader is also very interesting, haven't really looked too much into shaders yet. Stencil seems to do the job for me at the moment (aliasing isn't an issue right now) but I'll experiment a bit. Thanks again!
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 3 guests