Welding vertices at runtime

Yes, you can weld such vertices (unless any other vertex attributes are different like the UV coordinates). If two vertices have the same normal, you don’t have to do anything to the normal once you combined the two vertices since the normal is the same for both original vertices.

If you talk about this other question you’ve linked, that’s a different situation. When you have a shared vertex you will have a smooth shading at this vertex because you only have one normal per vertex. If the faces / triangles that meet at a vertex have different surface normals you only have two options:

  • use a shared vertex so you get smooth shading between the faces
  • use seperate vertices to get flat shading.

As it got mentioned before, whenever you have any vertex attribute that should be different (this includes the position, normal or uv texture coordinates) you have to split the vertex into seperate vertices.

2 Likes

My game looks like a minecraft but my game is not with cubes. My game looks like a 7 Days to Die and Rust game. You can/remove add walls, floor to make buildings.

And I will generate new terrain like in the minecraft, so this is not important. The main thing is a construction. I can build wall, floor, and so on.
So my objects look like this.

How can I save, load and draw all these meshes? So for this I use Chunk. You can see chunks in the picture. I added green box to show the chunks.

On every terrain have 500 chunks.

And each chunk gets 1000 objects. So each chunk can get, save, load and draw max 1000 objects. 500 Chunks * 1000 objects in each chunk = 500,000 objects has drew on the scene. Total 500 chunks draw max 500,000 objects. There is 500 draw meshes (I mean chunk). There are not 500,000 meshes (Just 500 chunks draw like this huge objects). Each chunk can draw 1000 objects. So I can draw this huge objects in 1 second, that’s good. But there is a problem with vertices. Because unity add extra vertices. normals, triangles and uvs. I know why unity do this, but I want to reduce vertices as I can. So all these 500,000 objects shows 12 - 13 million vertices and 6 million triangles and I get 25-30 FPS. So I want to reduce vertices for performance. I could reduce vertices, normals, uvs and I get 50 FPS with 500,000 objects. And you can see the performance. I made from 25 fps to 50 FPS. So it’s good. But now I got a new problem with normal and I asked here to solve this normal problem. So if you have another idea how to solve this then I will be happy to hear some help/idea.

Then I need calculate uvs too, so ok, now I get it. If there are same normal and uv values then I can weld that 2 vertices and not touching to normal and uv values. I get it. I will test this.

By the way, I have get this code from this answered question link

https://answers.unity.com/questions/1382854/welding-vertices-at-runtime.html

I used @imaxus code to share vertices and it has worked. But your code did not worked for me, I do not know why. Even I did get any error messages from your code.

And there is another problem in his code it takes a long time to search same vertices. I have read some posts that HashSet and Dictionary are fast for searching. @imaxus used Dictionary but it did not make a scene and it still takes a long time to find same vertices. I wait (2-3 minutes for searching). I think there is an issue with his code. Why Dictionary did not work fast in his code?

Can you avoid rendering distant chunks?

Have you tried ignoring vertexes and just merging the objects together? Are you sure it is the raw vertex count that is the problem?

Dictionary/Hashset are fast for searching, but they are not free. You are talking 10+million vertices. That is going to take some time.

1 Like

Just thought I’d add some random notes:

3D editing software like Blender shows abstracted versions of vertices. These fake vertices can have any number of uv’s and normals with a single position. So a cube has eight vertices according to Blender. However the hardware can’t render this, so in the background Blender will store / render the cube as 24 hardware vertices. Unity doesn’t add any extra data, Blender just hides it from you.

As soon as you add uv’s you have nearly no chance of doing a real weld. For example, in Blender I have an object with uv’s e.g. the Blender monkey mesh. If I select three vertices on a triangle and click merge then blender says that the total number of vertices has decreased by two and I have one less triangle. However, in the background the number of hardware vertices hasn’t changed because the uv’s are unique (the triangle is really gone).

As a 2D example, imagine you have a square piece of paper with a different color on each corner. These are unique like uv’s. You then make a copy of it, you can only merge them if the colors on the corners match. It doesn’t matter how you position or rotate them, you can’t get two corners to match. In a real example the uv’s would all be different so it’s like giving each corner a random color and hoping you find an edge that matches.

Static batching probably won’t help with that number of objects (I’m guessing the above example is just stress testing the limits). I’d suggest trying GPU instancing instead.

1 Like

have you looked into Marching Cubes?

you don’t want that many gameobject’s, single chunk can often be just one mesh.

For now camera just renderer to half of the terrain, It means if there are 500,000 objects on the terrain and if I am at the center of the terrain JUST I can see 250,000 objects. Yes, I do not render if that objects far away from camera.

So there are 500 chunks and I compressed 500,000 objects into 500 chunks (It means I merged my objects inside 500 chunks).

So, I also checked this. I thought that maybe my code is lagging and giving a problem. Then after drew my all meshes at the runtime and I paused the game and removed all scripts from chunks. And then I returned to the game and I saw that this does not make scene. Because now there are not a code and it still gives a 25-30 FPS. Shortly, yes. Not only vertex. There are vertex, normals and uvs also . So, I am trying to find another way, if I can.

Yes, I tested it. It takes 7-10 seconds to searching 10Million. vertices

I thought like this. But I wasn’t sure. Now I get it.

Maybe I can nor weld vertices because of the different uvs and normals. But I do not know I will find another way.

Do you mean “Enable Instancing” on the material? Or need I add some code into c# or I need to write shader? How? I did not understand.

Really I did not understand this. If there is an easy tutorial with examples. Then it would be great.

So there are 500 chunk objects. And each chunk objects draw 1000 objects. So can marching cube system draw up to 20 Million vertices?

this would be a highend example, can build, break, generate endlessly etc.

1 Like

GPU instancing is fairly easy to set up if you’re just using the standard shader, just tick the “Enable GPU instancing” on the material. To test it, create a large number of the same mesh with the instanced material applied. Run the game, enter the game tab and click “Stats”. You should see “Saved by batching” increase with instancing enabled on the material.

GPU instancing changes how data is sent to the graphics card. Normally if I had 100 instances of a 10,000 vert mesh I would end up making 100 draw calls and would send 1,000,000 verts of total data. With instancing it makes one draw call by passing the 10,000 vert mesh once to the graphics card along with the position, rotation and scale of each object.

It’s only really useful if you have lots of instances of the same mesh / material.

It would probably be easier to just use an existing engine like the one @mgear linked.

1 Like

I enabled instancing in the material. It did not help (same FPS). If you mean fps is dropping due to material, but I don’t think so. Because there is a fps drop even without material.

Maybe do you mean need I write some shader for this or how?
Or otherwise if you mean this Material Enable Instancing. But, It did not help.

@GameDeveloperAf :
I know this a bit off topic, but if you want to draw a lot of vertices on the scene with Unity, with good FPS, without sacrificing normals you can use NanoTech, it will be probably released end of this year:

:wink: