Page 1 of 2

Opposite colors to the background

Posted: Thu Feb 21, 2019 2:14 am
by Charlie Gallie
Hello, let me start of by telling you that I'm not that amazing with Love or lua for that matter.

Now, I want to create a circle just like

Code: Select all

love.graphics.circle("line", circle.x, circle.y, circle.r)
(the size and position work just fine) but I have an image as a background and I want the color of the circle to be the opposite color of which it's above. I don't know if this is even possible but all help is seriously appreciated! :awesome:

Thanks!

Re: Opposite colors to the background

Posted: Thu Feb 21, 2019 11:29 am
by grump
Charlie Gallie wrote: Thu Feb 21, 2019 2:14 am Now, I want to create a circle just like

Code: Select all

love.graphics.circle("line", circle.x, circle.y, circle.r)
(the size and position work just fine) but I have an image as a background and I want the color of the circle to be the opposite color of which it's above.
I suppose you mean that the circle should invert the color that is already on the screen? You need a Shader and a Canvas to achieve that, because there is no "invert" blendmode in LÖVE.

Code: Select all

local background = love.graphics.newCanvas()
local invert = love.graphics.newShader([[
	extern Image background;

	vec4 effect(vec4 color, Image texture, vec2 uv, vec2 fc) {
		return vec4(1.0 - Texel(background, uv).rgb, 1.0);
	}
]])
invert:send('background', background)

function love.draw()
	background:renderTo(function()
		-- draw the background contents here
		love.graphics.clear(1, 0, 0)
	end)
	love.graphics.draw(background) -- draw background on screen

	-- draw circle with invert shader
	love.graphics.setShader(invert)
	love.graphics.circle('fill', 100, 100, 100)
	love.graphics.setShader()
end

Re: Opposite colors to the background

Posted: Thu Feb 21, 2019 11:31 am
by pgimeno
Edit: Oops, ninja'd by grump :nyu:

You need a shader. If your background is not an image, you also need a canvas where you draw the background.

The shader would be like this:

Code: Select all

local shader = love.graphics.newShader[[
  extern Image background;

  vec4 effect(vec4 colour, Image texture, vec2 texpos, vec2 scrpos)
  {
    vec4 fgpixel = Texel(texture, texpos) * colour;
    vec4 bgpixel = Texel(background, scrpos/love_ScreenSize.xy);
    return vec4(fgpixel.rgb - bgpixel.rgb, fgpixel.a);
  }
]]
You need to send the background image or canvas to the shader with:

Code: Select all

  shader:send('background', backgroundImageOrCanvas)
Attached is a complete example.

Re: Opposite colors to the background

Posted: Thu Feb 21, 2019 11:34 am
by grump
pgimeno wrote: Thu Feb 21, 2019 11:31 am Edit: Oops, ninja'd by grump :nyu:
Ha! :) But you walked the extra mile, while I was lazy as usual. Edit: and my solution wouldn't even work right with an actual background because the texture coords are bogus

An 'invert' blendmode would be useful to have.

Re: Opposite colors to the background

Posted: Thu Feb 21, 2019 1:13 pm
by Charlie Gallie
pgimeno wrote: Thu Feb 21, 2019 11:31 am Edit: Oops, ninja'd by grump :nyu:

You need a shader. If your background is not an image, you also need a canvas where you draw the background.

The shader would be like this:

Code: Select all

local shader = love.graphics.newShader[[
  extern Image background;

  vec4 effect(vec4 colour, Image texture, vec2 texpos, vec2 scrpos)
  {
    vec4 fgpixel = Texel(texture, texpos) * colour;
    vec4 bgpixel = Texel(background, scrpos/love_ScreenSize.xy);
    return vec4(fgpixel.rgb - bgpixel.rgb, fgpixel.a);
  }
]]
You need to send the background image or canvas to the shader with:

Code: Select all

  shader:send('background', backgroundImageOrCanvas)
Attached is a complete example.
Thank you so much! This has helped an unbelievable amount! :awesome:

Re: Opposite colors to the background

Posted: Thu Feb 21, 2019 2:06 pm
by ivan
An 'invert' blendmode would be useful to have.
This is by far the easiest way to do it and it doesn't require shaders.
It should be possible using the "subtract" blend mode but I've never been able to get it working in Love2D.

Re: Opposite colors to the background

Posted: Thu Feb 21, 2019 2:41 pm
by Charlie Gallie
ivan wrote: Thu Feb 21, 2019 2:06 pm
An 'invert' blendmode would be useful to have.
This is by far the easiest way to do it and it doesn't require shaders.
It should be possible using the "subtract" blend mode but I've never been able to get it working in Love2D.
Yeah, but the code he's given me works perfectly for what I need so there's not really any reason to change my method. :nyu:

Re: Opposite colors to the background

Posted: Thu Feb 21, 2019 2:46 pm
by grump
ivan wrote: Thu Feb 21, 2019 2:06 pm
An 'invert' blendmode would be useful to have.
This is by far the easiest way to do it and it doesn't require shaders.
Blending in LÖVE is weird. I for example never really understood why multiplicative blending can only be used with premultiplied alpha, and does not multiply the alpha component.

It would be nice if we could set source and dest blending parameters independently from each other.

Re: Opposite colors to the background

Posted: Thu Feb 21, 2019 3:10 pm
by zorg
Yep, would be nice if these would be options; not sure whether GL and GL ES version intercompatibility is the barrier to this or not though.

https://www.khronos.org/registry/OpenGL ... parate.xml
https://www.khronos.org/registry/OpenGL ... parate.xml

Also, subtract doesn't work because to invert a color you'd want to do source minus dest, like 1-R,1-G,1-B (and some type of alpha); but löve's exposed subtract blendmode can only do dest minus source, so R-1, G-1, B-1; that doesn't invert color values (the ones are the source colors, and the letters are the destination colors)

Re: Opposite colors to the background

Posted: Thu Feb 21, 2019 4:59 pm
by Charlie Gallie
zorg wrote: Thu Feb 21, 2019 3:10 pm Yep, would be nice if these would be options; not sure whether GL and GL ES version intercompatibility is the barrier to this or not though.

https://www.khronos.org/registry/OpenGL ... parate.xml
https://www.khronos.org/registry/OpenGL ... parate.xml

Also, subtract doesn't work because to invert a color you'd want to do source minus dest, like 1-R,1-G,1-B (and some type of alpha); but löve's exposed subtract blendmode can only do dest minus source, so R-1, G-1, B-1; that doesn't invert color values (the ones are the source colors, and the letters are the destination colors)
Thank you so much, you've all helped so much! :awesome: