Meshlets Merging and Simplification. #569
Replies: 1 comment 7 replies
-
The way I would approach this I think is I would create a small fictional vertex buffer & index buffer that has a fairly small number of vertices and triangles and is indexed locally. It's possible to only work with indices but Sketch (not tested or compiled) below. I would also recommend using more than two source meshlets as that provides the maximum amount of freedom for the simplifier. Also you'd want to use meshopt_SimplifyLockBorder flag to ensure that the resulting set of triangles doesn't have gaps with independently simplified groups of neighboring clusters. struct ClusterVertex { vec3 position; unsigned int index; }; // index = original index in the original vertex buffer
// assumed state:
// unsigned int* meshlet_vertices - aggregate array of vertex indices for meshlet data
// unsigned char* meshlet_triangles - aggregate array of triangle indices for meshlets
// Vertex* vertices - actual vertex buffer that meshlet_vertices[] refers to
// temporary; indices refer to position within local_vertices
std::vector<ClusterVertex> local_vertices;
std::vector<unsigned int> local_indices;
// local_vertices & local_indices can be reserved to the full size with an extra loop
// merge meshlets into a big mesh, with local_indices referring to local_vertices; local_vertices tracks original vertex buffer index
for (meshopt_Meshlet m : children)
{
size_t local_offset = local_vertices.size();
for (unsigned int v = 0; v < m.vertex_count; ++v)
{
unsigned int global_index = meshlet_vertices[m.vertex_offset + v];
local_vertices.push_back(ClusterVertex { vertices[global_index].position, global_index });
}
for (unsigned int t = 0; t < m.triangle_count; ++t)
{
local_indices.push_back(local_offset + meshlet_triangles[m.triangle_offset + t * 0]);
local_indices.push_back(local_offset + meshlet_triangles[m.triangle_offset + t * 1]);
local_indices.push_back(local_offset + meshlet_triangles[m.triangle_offset + t * 2]);
}
}
// simplify the resulting small mesh (0.5 factor)
int target_index_count = int((local_indices.size() / 3) * 0.5) * 3;
local_indices.resize(meshopt_simplify(&local_indices[0], &local_indices[0], local_indices.size(), &local_vertices[0].position.x, local_vertices.size(), sizeof(ClusterVertex), target_index_count, 1e-2f, meshopt_SimplifyLockBorder));
// construct a index buffer that refers to the original (global / per-mesh) vertex array
std::vector<unsigned int> global_indices;
global_indices.reserve(local_indices.size());
for (size_t i = 0; i < local_indices.size(); ++i)
global_indices.push_back(local_vertices[local_indices[i]].index);
// now you have a real small index buffer (global_indices) that represents the simplification of a union of the input meshets, and you can split it into meshlets again by calling meshopt_buildMeshlets again. |
Beta Was this translation helpful? Give feedback.
-
Since the meshopt_meshlet is purely indexing structs for outputing meshlet_triangles and vertices. I would like to know how could I merge two meshlets and then simplify their geometry. Could anyone please explain that process to me, I'm having a hard time dealing with the indirection of all indexes to properly achieve that. This is What I tried so far.
//Merge the geomtry of the two neighbor clusters
Beta Was this translation helpful? Give feedback.
All reactions