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.
Weird outline around objects when using blendmode
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
-
- Prole
- Posts: 3
- Joined: Sat Nov 02, 2013 2:53 am
Weird outline around objects when using blendmode
- Attachments
-
- lighting_test.love
- Copy of my game code so far
- (35.16 KiB) Downloaded 150 times
-
- Prole
- Posts: 3
- Joined: Sat Nov 02, 2013 2:53 am
Re: Weird outline around objects when using blendmode
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.
Re: Weird outline around objects when using blendmode
Love 0.8.0:
Love 0.9.0:
do so in love.load
also your sprites outline is in shades of white.
Code: Select all
love.graphics.setDefaultImageFilter("nearest", "nearest")
Code: Select all
love.graphics.setDefaultFilter("nearest","nearest")
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.
Re: Weird outline around objects when using blendmode
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.
Re: Weird outline around objects when using blendmode
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.
Check out my blog on gamedev
Re: Weird outline around objects when using blendmode
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.
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.
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
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.
-
- Prole
- Posts: 3
- Joined: Sat Nov 02, 2013 2:53 am
Re: Weird outline around objects when using blendmode
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.
- 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
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.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.
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
Who is online
Users browsing this forum: Google [Bot] and 7 guests