Weird outline around objects when using blendmode

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
digitalarchitect
Prole
Posts: 3
Joined: Sat Nov 02, 2013 2:53 am

Weird outline around objects when using blendmode

Post by digitalarchitect »

Could someone please help me sort out a weird problem I've been having in my game? I'm fairly new to game development and I've just started messing around with some basic lighting using a second canvas as a lighting mask. I found this post viewtopic.php?f=4&t=11990 which worked alright but when I did something similar in my game I ended up with a weird glow around a lot of the objects on the screen.

I've attached a screenshot showing the effect. Notice that of the small pieces of food near the character 1 has a white edge around it while another doesn't. If you want to try out the LOVE file you can use the arrow keys to move, press P to place plant, F to place a piece of food or space to pause the game. Does anyone have any ideas what could be causing this? If you need any more detail just let me know.
Attachments
Screenshot of the bad lighting effects
Screenshot of the bad lighting effects
bad_lighting.png (41.01 KiB) Viewed 4609 times
lighting_test.love
Copy of my game code so far
(35.16 KiB) Downloaded 150 times
digitalarchitect
Prole
Posts: 3
Joined: Sat Nov 02, 2013 2:53 am

Re: Weird outline around objects when using blendmode

Post by digitalarchitect »

A quick update, I have just discovered that it only happens when items have a non-integer x or y. If I use math.floor on the positions before I draw them the effect goes away for the wheat (which is a pixelated image) but not for the bugs or food (which have smooth images). This leads me to believe that something about the pixels around the objects is getting multiplied when the images are blended, making the outline white. Still don't have any ideas as to how to properly fix it though.
szensk
Party member
Posts: 155
Joined: Sat Jan 19, 2013 3:57 am

Re: Weird outline around objects when using blendmode

Post by szensk »

Love 0.8.0:

Code: Select all

love.graphics.setDefaultImageFilter("nearest", "nearest")
Love 0.9.0:

Code: Select all

love.graphics.setDefaultFilter("nearest","nearest")
do so in love.load

also your sprites outline is in shades of white.
Last edited by szensk on Sat Nov 02, 2013 10:28 am, edited 1 time in total.
User avatar
Plu
Inner party member
Posts: 722
Joined: Fri Mar 15, 2013 9:36 pm

Re: Weird outline around objects when using blendmode

Post by Plu »

Are you using spritemaps? Might also be that your images need an extra lines of pixels around them in the same color as the adjacent pixel due to rounding when drawing them.
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Weird outline around objects when using blendmode

Post by micha »

I had a similar problem. The problem was, that the transparent color around the image was "white transparent" (that means that alpha is 0, but the color is (255,255,255) ). If you set the background color to "black transparent" instead (alpha = 0, and color = (0,0,0)) then it should work alright.
User avatar
Boolsheet
Inner party member
Posts: 780
Joined: Wed Dec 29, 2010 4:57 am
Location: Switzerland

Re: Weird outline around objects when using blendmode

Post by Boolsheet »

micha is on the right track, but making it transparent black just makes the outline black, although that might be less noticeable. This behaviour comes from the alpha blend mode and how it uses the alpha of the pixel in the framebuffer.

To get rid of it properly, you have to use the premultiplied blend mode. This blend mode will blend the image in such a way that you get your expected result. However, you have to prepare your images for it. The red, green, and blue channels have to be multiplied by the alpha channel (hence premultiplied). You don't have to do this operation at runtime, my following example just shows how it would work.

This example draws four images. The two on the left with alpha blend mode and the two on the right with the prepared images and the premultiplied blend mode. With the two on the left, you can see how it interpolates the color of the transparent pixel. The images on the right do appear as we all would expect.

Code: Select all

function love.load()
	imgd1 = love.image.newImageData(128, 128)
	imgd2 = love.image.newImageData(128, 128)

	-- Black rectangle with a red circle and everything else being transparent white.
	imgd1:mapPixel(function(x, y, r, g, b, a)
		if x > 50 and x < 100 and y > 30 and y < 80 then
			if ((x - 74)^2 + (y - 54)^2)^0.5 < 20 then
				return 255, 0, 0, 255
			end
			return 0, 0, 0, 255
		end
		return 255, 255, 255, 0
	end)

	-- White rectangle with a red circle and everything else being transparent black.
	imgd2:mapPixel(function(x, y, r, g, b, a)
		if x > 50 and x < 100 and y > 30 and y < 80 then
			if ((x - 74)^2 + (y - 54)^2)^0.5 < 20 then
				return 255, 0, 0, 255
			end
			return 255, 255, 255, 255
		end
		return 0, 0, 0, 0
	end)

	img1 = love.graphics.newImage(imgd1)
	img2 = love.graphics.newImage(imgd2)

	-- Multiplying the red, green, and blue channels with the alpha channel.
	imgd1:mapPixel(premutlipliedFunction)
	imgd2:mapPixel(premutlipliedFunction)

	img3 = love.graphics.newImage(imgd1)
	img4 = love.graphics.newImage(imgd2)

	x1, y1 = 0, 0
	x2, y2 = 0, 0
end

function premutlipliedFunction(x, y, r, g, b, a)
	return (r * a) / 256, (g * a) / 256, (b * a) / 256, a
end

function love.update(dt)
	x1 = (x1 + dt * 5) % 400
	y1 = (y1 + dt * 3) % 200
end

function love.draw()
	-- Making the lower half of the window white.
	love.graphics.rectangle("fill", 0, 300, 800, 300)

	-- Drawing the images with alpha blend mode.
	love.graphics.setBlendMode("alpha")
	love.graphics.draw(img1, 20 + x1, 100 + y1)
	love.graphics.draw(img2, 20 + x1, 400 + y1)

	-- Drawing the premultiplied images with premultiplied blend mode.
	love.graphics.setBlendMode("premultiplied")
	love.graphics.draw(img3, 200 + x1, 100 + y1)
	love.graphics.draw(img4, 200 + x1, 400 + y1)
end
Of course you can also just always draw at integer coordinates as suggested.

The alpha blend mode in the upcoming LÖVE 0.9.0 was slightly changed so this operation is not necessary anymore.

Edit: Oh, I see you use the multiplicative blend mode. This one has a bit of a weird behaviour in 0.8.0. I need to do some more poking before I can explain that.
Edit2: I think I get it now. The 0.8.0 multiplicative blend mode uses the alpha in a specific way. This gives probably unexpected behaviour if the image that gets drawn has translucent parts. I would recommend to only blend opaque images with this mode, which is a bit tricky if stuff has been drawn with the alpha blend mode. You already do make the 'scene' canvas opaque with that grass color. All you have to do now is to premutliply the images and draw them with the premultiplied blend mode.

Oh, and before i forget it. There's an issue with the premultiplied blend mode in 0.8.0 with fonts and smooth lines. They don't really work with it. This all gets better in 0.9.0 with the changed alpha blend mode.
Shallow indentations.
digitalarchitect
Prole
Posts: 3
Joined: Sat Nov 02, 2013 2:53 am

Re: Weird outline around objects when using blendmode

Post by digitalarchitect »

In the short term I've changed to integer coordinates as szenk suggested. I'll probably continue with this as my graphics are going to be fairly blocky anyway. Thanks for the suggestions about the blend mode though, I'll have a closer look at it tonight. Is 0.9.0 ready to start using or is it still a development version? I might look at moving to it if it's not too difficult. I figure I might as well shift if it's not too hard while my game is pretty basic. Thanks for everyone's help though.
User avatar
slime
Solid Snayke
Posts: 3162
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Weird outline around objects when using blendmode

Post by slime »

digitalarchitect wrote:Is 0.9.0 ready to start using or is it still a development version? I might look at moving to it if it's not too difficult. I figure I might as well shift if it's not too hard while my game is pretty basic. Thanks for everyone's help though.
It's ready to start using - a lot of the links to new 0.9.0 documentation are automatically 'hidden' from the regular sections of the wiki until it's actually released though, which can be annoying.

This page has download links to fairly up-to-date development versions of 0.9.0 for Windows and OS X: http://nightly.projecthawkthorne.com
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 2 guests