unique and shared vertices

Just a quick question about shared and unique vertices when generating meshes.

I moved from shared vertices to unique vertices to be able to assign each quad a texture from an atlas via the uv coordinates.

Now i dont need that part anymore since i moved to a different approach and am using submeshes to assign materials. Does this require unique vertices or do submeshes work with shared vertices also?

You still need unique vertices. Submeshes are only extra triangle lists, all other data is shared.

Thanks for pointing out. Still a bit confused - will test some things out to understand.

IF any shared vertices do not share a uv coord then they have to be split

1 Like

Haha, im getting confused more and more :slight_smile: so here goes the context:

I’m creating a tilemap. At first i used shared vertices, then i switched to unique vertices to be able to be able to map tiles from an atlas on to the tiles individually.

I don’t need this uv mapping anymore - but im dynamically creating submeshes, if a tile changed. Now my question was, if i still need unique vertices for this or if can fall back to shared. From my understanding it should work with shared ones - but i didnt want to corrupt my code just for testing purpose at this point - so i asked.

I do it like this for each quad i’m iterating through:

	Vector3[] getVertices(Vector3 pos) {

		Vector3[] v = new Vector3[4] {
			new Vector3 (pos.x				, pos.y		, pos.z),
			new Vector3 (pos.x + _tileSize	, pos.y		, pos.z),
			new Vector3 (pos.x				, pos.y		, pos.z + _tileSize),
			new Vector3 (pos.x + _tileSize	, pos.y		, pos.z + _tileSize)
		};

		return v;
	}

	Vector3[] getNormals() {
		
		Vector3[] n = new Vector3[4] {
			Vector3.up,
			Vector3.up,
			Vector3.up,
			Vector3.up
		};
		
		return n;
	}


	Vector2[] getUVS() {
		
		Vector2[] u = new Vector2[4] {
			new Vector2(0, 0),
			new Vector2(1, 0),
			new Vector2(0, 1),
			new Vector2(1, 1)
		};
			
			return u;
	}

	int[] getTriangles(int cnt) {
		
		int[] t = new int[6] {
			cnt + 0,
			cnt + 2,
			cnt + 1,
		
			cnt + 2,
			cnt + 3,
			cnt + 1
		};

		return t;
	}

So, wouldnt submeshes also work if i gave back the 2 vetices of the last quad and add the 2 new ones?

The reason for this question wasn’t the point to possibly get rid of some unnecessary vertices, which would be ok if possible, but the fact that when i deform my mesh: set some vertices higher or lower: the unique vertices approach breaks up my mesh. So when deforming the mesh i’d need to also move the vertice of the neighbouring tile with the “same” but each unique Vector3.

So you have opted for having a different material for each submesh? You are aware this means a new draw call for each material?

Obviously I do not know what exactly you are doing without further explanations etc… but you do mention your issue with the first method was because of moving vertices and then having to know to move neighbouring vertices so here is some food for thought if it helps any and if applicable to your specific scenario…

SO with only having one mesh and one vertices array supporting split vertices…

In my organic to voxel converter system im currently finishing off I use a logic of an intersection class for each junction in the grid. In a 3D grid this means 8 corners meet at any one intersection/junction , for a 2D system like yours it would mean 4.

The intersection class has only one position vector for the junction.

You then map each corner of each tile to the relevant intersection class. Store a reference/key to each intersection for each corner etc

You can store and update all sorts of shared information in the intersection class which the tiles can use… eg In my system I use it for Vertex optimization , edge splitting , AO values , boneWeights etc… many things

So to create the final mesh you would loop your tile collection , and each tile can pull each corner vertex position from the relevant intersection. The very first time the intersections position is injected into the final vertices array you store that index and set a flag to state its been used

As the loop progresses for any other tile corner that shares that intersection it can easily opt to share the vertex or split the edge. If you choose to share it then you simply copy the stored index. If you split the vertex you copy the position vector and inject it again and store that new index.

So each tile has a reference to the index of each corner in the final array - shared or split doesnt matter.

For deformation then , you would only have to deform the intersections positions and thereafter update your tile or tiles collection which would pull the deformed vertex value for each corner from the mapped intersection and inject it into the stored index position in the final array again.

I use some extra booleans to facilitate not processing shared data twice.

I guess it might sound very complicated but it works for me.

hth

Yes i’m aware of each material in a submesh having a separate drawcall. At first i had 1 submesh and material for each tile. Due to performance i modified it, to dynamically reassign submeshes, when a tile is sharing a material with another one - that works pretty well.

Your scheme souns interesting allthough i cant grasp the application for it since “Vertex optimization , edge splitting , AO values , boneWeights etc…” is all knew to unknown for me :stuck_out_tongue: - i’m just starting out…

I’m sure i misconceive some aspect of vertice and triangle arrays and need to test it, since i can’t explain what i don’t get :slight_smile: Thanks for your time trying to help me out!