Image Filter artefacts when zoomed

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.
DrDaveDeath
Prole
Posts: 4
Joined: Thu Jan 16, 2014 1:26 pm

Image Filter artefacts when zoomed

Post by DrDaveDeath »

Hi there -

I'm currently prototyping a game out, I have a bunch of tiles in a quad and I'm drawing them based on a grid. The problem I am having, after scaling upwards (using gamera, not sure if that's relevant or not), I am seeing artefacts when moving. I've taken some screenshots:

Image
This one is fine

Image
Notice the white lines. They sort of flicker, not always visible.

I have love.graphics.setDefaultFilter('nearest', 'nearest') set.

The tileset I'm using:
Image

Think I am loading the quads in a normal fashion:

Code: Select all

 	
Quads = {
		love.graphics.newQuad(0, 0, tileW, tileH, tilesetW, tilesetH),
		love.graphics.newQuad(0, 64, tileW, tileH, tilesetW, tilesetH),
		love.graphics.newQuad(0, 128, tileW, tileH, tilesetW, tilesetH),
		love.graphics.newQuad(0, 192, tileW, tileH, tilesetW, tilesetH),
		love.graphics.newQuad(0, 256, tileW, tileH, tilesetW, tilesetH)
}
Any ideas?

Edit: Probably worth noting that I have

Code: Select all

for rowIndex=1, #dungeon do
		local row = dungeon[rowIndex]
		for columnIndex=1, #row do
			local number = row[columnIndex]
			love.graphics.draw(tileSet, Quads[number], (columnIndex-1)*tileW, (rowIndex-1)*tileH)
		end
	end
in my love.draw.
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Image Filter artefacts when zoomed

Post by Jasoco »

Use math.floor() for the image draw coordinates. You're drawing them at decimal positions.

Also remember that you're going to have this problem if you scale to anything that's not a whole number.

An alternative advanced method is to draw to a canvas at 100% and scale that.

Also, a better way of creating the quads:

Code: Select all

Quads = {}
for i = 1, (tilesetH / tileH)
  Quads[i] = love.graphics.newQuad(0, (i-1) * tileH, tileW, tileH, tilesetW, tilesetH)
end
User avatar
slime
Solid Snayke
Posts: 3162
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Image Filter artefacts when zoomed

Post by slime »

If you 'expand' the border pixels of each sub-image in your tileset by 1px on each side (and account for the new padding when making your Quads), the problem should go away.

You can do this programmatically with ImageData functions if you want.
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Image Filter artefacts when zoomed

Post by Jasoco »

The problem being demonstrated here will be fixed by simply flooring the coordinates. And making sure to only scale at whole numbers.
User avatar
slime
Solid Snayke
Posts: 3162
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Image Filter artefacts when zoomed

Post by slime »

Jasoco wrote:The problem being demonstrated here will be fixed by simply flooring the coordinates. And making sure to only scale at whole numbers.
That's a workaround - and it won't work very well when other types of graphics transformations are applied.

Here is what another website says:
Starling wiki wrote: Tiling images on the GPU involve some gotchas. If your images aren't drawn to whole pixels or they are scaled, the textures may bleed a bit and cause unsightly lines or empty gaps between images. During animations, flickering may happen where textures meet as these gaps quickly appear and disappear. It can help to always ensure that your display objects aren't placed on fractional pixels, but that can be an exercise in frustration, especially on a deep display list.

The popular Texture Packer software, used to create texture atlases, offers a useful feature named “Extrude”. When you enable this feature, the pixels around the edges of your sub-textures will be duplicated, but it won't change the size of your sub-textures. The duplicated pixels appear just outside the sub-texture's bounds. When texture bleeding happens, the same color that appears on the edge of the sub-texture will bleed into the bounds instead of a transparent pixel or another color.

When tiling images, extruding is always recommended.
[It takes just a bit of time to duplicate the extrusion behaviour of Texture Packer programmatically in LÖVE or somewhere else.]
DrDaveDeath
Prole
Posts: 4
Joined: Thu Jan 16, 2014 1:26 pm

Re: Image Filter artefacts when zoomed

Post by DrDaveDeath »

Many thanks for the replies guys. Really fast. What a great community.

I manually extruded my tiles for now and that fixed the issue. Will look into an app that sorts that out for me later :)

Thanks again!
DrDaveDeath
Prole
Posts: 4
Joined: Thu Jan 16, 2014 1:26 pm

Re: Image Filter artefacts when zoomed

Post by DrDaveDeath »

Jasoco wrote:Use math.floor() for the image draw coordinates. You're drawing them at decimal positions.

Also remember that you're going to have this problem if you scale to anything that's not a whole number.

An alternative advanced method is to draw to a canvas at 100% and scale that.

Also, a better way of creating the quads:

Code: Select all

Quads = {}
for i = 1, (tilesetH / tileH)
  Quads[i] = love.graphics.newQuad(0, (i-1) * tileH, tileW, tileH, tilesetW, tilesetH)
end
I've been playing around with this method of creating the Quads, although I am presuming the limitation here is that if I am padding each quad by 1, I can't use this method? Or am I just being dense?
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Image Filter artefacts when zoomed

Post by Jasoco »

I don't believe in the extrusion method myself. (It's not required at all if you're only scaling to whole numbers and just floor the x and y when drawing) But just make the quad size the same as the extruded tile. Easy as pie.
User avatar
verilog
Citizen
Posts: 97
Joined: Thu Nov 03, 2011 3:15 am
Contact:

Re: Image Filter artefacts when zoomed

Post by verilog »

The best solution, as Slime pointed out, is padding each tile with a 1 pixel border with the color of the neighbouring pixel, this will get rid of the issue under all possible image transformations. I believe this issue has to do with how OpenGL uses the neighbouring pixel color (that falls outside of your tile) while drawing at non-integer coordinates. The direct workaround, as Jasoco suggested, is drawing at integer positions (using math.floor). However, there could be other transformations (e.g. rotation) that would still be rendered incorrectly.
DrDaveDeath
Prole
Posts: 4
Joined: Thu Jan 16, 2014 1:26 pm

Re: Image Filter artefacts when zoomed

Post by DrDaveDeath »

DrDaveDeath wrote:
Jasoco wrote:Use math.floor() for the image draw coordinates. You're drawing them at decimal positions.

Also remember that you're going to have this problem if you scale to anything that's not a whole number.

An alternative advanced method is to draw to a canvas at 100% and scale that.

Also, a better way of creating the quads:

Code: Select all

Quads = {}
for i = 1, (tilesetH / tileH)
  Quads[i] = love.graphics.newQuad(0, (i-1) * tileH, tileW, tileH, tilesetW, tilesetH)
end
I've been playing around with this method of creating the Quads, although I am presuming the limitation here is that if I am padding each quad by 1, I can't use this method? Or am I just being dense?
FYI for those interested, to get around the padding I did:

Code: Select all

Quads[i] = love.graphics.newQuad(1, (i-1) * 66, tileH, tileY, tilesetW, tilesetH)
66 being 64 + 2 padding cells.
Post Reply

Who is online

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