I have a question regarding vertices count difference between Blender and Godot imported meshes. For the example I am using Blender to model this simple double plane object. It contains 6 vertices as shown by blender:
When exporting to the OBJ format, we can also see that the meshes contains 6 vertices:
# Blender 4.5.3 LTS
# www.blender.org
mtllib plane.mtl
o Plane
v 0.000000 0.000000 0.000000
v 2.000000 0.000000 0.000000
v 0.000000 0.000000 -2.000000
v 2.000000 0.000000 -2.000000
v 0.000000 2.000000 -2.000000
v 2.000000 2.000000 -2.000000
vn -0.0000 1.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
s 0
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3/4/2 4/3/2 6/3/2 5/4/2
However, after importing the mesh into Godot and using it, the vertex count increases to 8. I use this script to retrieve the number of vertex from the Mesh:
@tool
extends Node3D
@export_tool_button("Get Mesh Info", "Callable") var _get_mesh_info_button = _get_mesh_info
@onready var plane: MeshInstance3D = $plane
func _get_mesh_info() -> void:
var mesh: Mesh = plane.mesh
for i in range(mesh.get_surface_count()):
for array: Variant in mesh.surface_get_arrays(i):
print(array)
The script is attached to my TestPlane node to expose a button in the editor than retrieves information about the plane Mesh:
We can see from the screenshot above that the Mesh contains 8 vertices in the first line of the debugger output. I get that Godot replaces quads with triangles during Mesh import, but why does it duplicate vertices instead of reusing the same ones for multiples triangles when possible?
For instance we can see that the (0.0, 0.0, -2.0) and the (2.0, 0.0, -2.0) vertices are duplicated.
To sum up:
Why does Godot duplicate vertices instead of reusing the same ones for multiple triangles? Is it better for performance reason?
I believe this is due to how Blender and game engines render meshes differently.
I had the same issue on a university project once where faces had to be connected for displacement purposes. Just like you’re doing, I thought I was right to assume that the vertex count – and pretty much all other characteristics of the mesh – would be represented identically in the game engine. This is just not the case.
The base shading of a mesh (no textures etc.) relies on the respective vertex normals to compute and render the lighting for each face. If the mesh, in Blender, is configured with flat shading, each face (triangle or quad) will have it’s own vertices that it does not share with any other faces to achieve that flat shading. On the contrary, if set to use smooth shading, faces will either share vertices, or just their normals, to achieve the smooth shading.
If you need faces to be connected, a quick fix is to set the mesh in Blender to Shade Smooth. When exported, this should result in a mesh with the amount of vertices you’re expecting albeit with non-flat shading (due to interpolated normals).
I don’t think I’m explaining it that well. Hopefully it works out for you.
Let me know if you have any other questions.
EDIT:
How to view normals in Blender
You can view each type of mesh normal in Blender via a toggle in Edit mode in the top-right of the viewport.
The mesh data cannot separate the indices for different data, so all the colors, texture UVs, normals, tangents, etc., have to match for every time that vertex is used, if they don’t it has to be duplicated
Thanks for your answers!
Indeed, it is clearer now. I thought flat/smooth shading was some sort of parameter that was sent to GPU calls, but actually as I understand it, this information is already contained in the vertices information (position and normal). That would also mean that the GPU does normal interpolation in any case (be it flat or smooth shading) purely based on vertices normal information, if I understand it correctly.