Opposite colors to the background

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.
User avatar
Charlie Gallie
Prole
Posts: 14
Joined: Sun Mar 18, 2018 2:53 pm

Opposite colors to the background

Post 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!
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Opposite colors to the background

Post 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
User avatar
pgimeno
Party member
Posts: 3641
Joined: Sun Oct 18, 2015 2:58 pm

Re: Opposite colors to the background

Post 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.
Attachments
drawing-inverted.love
(117.93 KiB) Downloaded 149 times
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Opposite colors to the background

Post 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.
User avatar
Charlie Gallie
Prole
Posts: 14
Joined: Sun Mar 18, 2018 2:53 pm

Re: Opposite colors to the background

Post 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:
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Opposite colors to the background

Post 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.
User avatar
Charlie Gallie
Prole
Posts: 14
Joined: Sun Mar 18, 2018 2:53 pm

Re: Opposite colors to the background

Post 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:
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Opposite colors to the background

Post 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.
User avatar
zorg
Party member
Posts: 3465
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Opposite colors to the background

Post 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)
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
Charlie Gallie
Prole
Posts: 14
Joined: Sun Mar 18, 2018 2:53 pm

Re: Opposite colors to the background

Post 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:
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 1 guest