[SOLVED] How fix mesh-component quads tearing?

Hello, again trying to build isometric tilemap using mesh-component. Question: what might cause mesh quads tearing while zooming in and out using float values?

screenshot:

video:

What i tried to far:

  1. Pack textures into atlas
  2. Extrude borders
  3. Make quad rect smaller-bigger
  4. Make quad texture rect smaller-bigger
  5. Disable mipmaps
  6. Try another materials

Example:

quadmap.zip (103.9 KB)

follow up:

It looks like floating point precision to me.
How do you position the isometric tiles? Are their positions clamped to some “precision”, or are you using integers, or just some floating point calculation?

In short, the vertices must be the same, or it’s likely you’ll get artefacts like this.

Tried multiple attempts since then, here’s updated version.

mesh quads.zip (1.8 MB)

There function that control position vertices . Ortographic version works without tearing, but with isometric i tried multiple formulae to transfrom orto to iso coordinates, none works. I guess maybe problem is because tiled y coordinate starts at top to bottom, meanwhile defold from bottom to top.

local function set_pos_vertices(stream, offset, x, y, z, w, h, is_rotated)
	z = M.y_sort(x, y, z) -- sort must be before x, y

	if M.mode == M.MODES.ORTHOGRAPHIC then
		x = x * M.tile_width
		y = y * M.tile_height
	else -- isometric
		x, y = (x - y) * 16 - 16, (x + y) * 8
	end

	if is_rotated then
		-- v       3---2  indices
		-- |     > |B/A| > 1-2-3
		-- 0---u   0---1   1-3-0
		stream[offset + 01], stream[offset + 02], stream[offset + 03] = x + w, y, z
		stream[offset + 04], stream[offset + 05], stream[offset + 06] = x + w, y + h, z
		stream[offset + 07], stream[offset + 08], stream[offset + 09] = x, y + h, z
		---
		stream[offset + 10], stream[offset + 11], stream[offset + 12] = x + w, y, z
		stream[offset + 13], stream[offset + 14], stream[offset + 15] = x, y + h, z
		stream[offset + 16], stream[offset + 17], stream[offset + 18] = x, y, z
	else
		-- v       3---2   indices
		-- |     > |B/A| > 0-1-2
		-- 0---u   0---1   0-2-3
		stream[offset + 01], stream[offset + 02], stream[offset + 03] = x, y, z
		stream[offset + 04], stream[offset + 05], stream[offset + 06] = x + w, y, z
		stream[offset + 07], stream[offset + 08], stream[offset + 09] = x + w, y + h, z
		--
		stream[offset + 10], stream[offset + 11], stream[offset + 12] = x, y, z
		stream[offset + 13], stream[offset + 14], stream[offset + 15] = x + w, y + h, z
		stream[offset + 16], stream[offset + 17], stream[offset + 18] = x, y + h, z
	end
end

p.s. project contains 2 git branches (ortograhic and isometric)

could it be engine bug?

  1. i tried make quads from back to front, front to back.
  2. add z index to quads.
  3. use model shader with different setup. tilemap shader, tile shader.
  4. use various matrixes like x = (x-y), y = (x+y), x = (x+y), y = (x-y), so on…
  5. different triangle indexing and winding
  6. also tried not use buffers without 0 indexes

How exactly you did that? I’m pretty sure problem is related to float precision, as Mathias mentioned, so it should help.

In your function “set_pos_vertices” I just made “w” a little bit bigger and it solved the problem:

local function set_pos_vertices(stream, offset, x, y, w, h, z, is_rotated)
	w = w * 1.001 -- just simply like that
	z = M.y_sort(x, y, z)

	if M.mode == M.MODES.ISOMETRIC then
		x, y = (x - y) * 0.5 - 0.5, (x + y) * 0.5
	end
	
	if is_rotated then
		stream[offset + 01], stream[offset + 02], stream[offset + 03] = x+w, y,   z
		stream[offset + 04], stream[offset + 05], stream[offset + 06] = x+w, y+h, z
		stream[offset + 07], stream[offset + 08], stream[offset + 09] = x,   y+h, z
		---
		stream[offset + 10], stream[offset + 11], stream[offset + 12] = x+w, y,   z
		stream[offset + 13], stream[offset + 14], stream[offset + 15] = x,   y+h, z
		stream[offset + 16], stream[offset + 17], stream[offset + 18] = x,   y,   z
	else
		stream[offset + 01], stream[offset + 02], stream[offset + 03] = x,   y,   z
		stream[offset + 04], stream[offset + 05], stream[offset + 06] = x+w, y,   z
		stream[offset + 07], stream[offset + 08], stream[offset + 09] = x+w, y+h, z
		--
		stream[offset + 10], stream[offset + 11], stream[offset + 12] = x,   y,   z
		stream[offset + 13], stream[offset + 14], stream[offset + 15] = x+w, y+h, z
		stream[offset + 16], stream[offset + 17], stream[offset + 18] = x,   y+h, z
	end
end

(before expanding “w”, it had same white lines as you shown in your video)

By the way love the style and smooth zoom! But please consider allowing only integers as target zoom value, it looks much more pleasant in such case :wink:

5 Likes

thanks! seems fixed now.

4 Likes

This is nice!
I have never implemented 2.5d isometric game, how do you implement collisions?
I mean for walls or objects, you cannot just use box2d collisions objects, since you need to pass in front or behind of objects…
Do you do 3D physics?

1 Like

that suppose to be tycoon game where you can select facilities and actors.

  1. actors can be selected with convex hull shape and raycast.
  2. facilities are mapped to tiles(which can reserve multiple tiles), so screen coord > to world coord > to cell coord to get facility.
  3. and maybe objects like item drop but they can selected like actors

so there are minimal collision involved.

2 Likes