Pack to Points.
Calculate Bound Sphere.
Create Lod0 meshlets.
meshlets of last lod.
Pack to Points.
Calculate Bound Sphere.
Pack Sparse Inputs.
Simplify meshlets group primPoints.
Simplify succeed: merge result to meshlets.
Pack to Points.
Calculate Bound Sphere.
Create Lod0 meshlets.
meshlets of last lod.
Pack to Points.
Calculate Bound Sphere.
Pack Sparse Inputs.
Simplify meshlets group primPoints.
Simplify succeed: merge result to meshlets.
18 {
20
24 {
25 auto primVertices = meshPack->m_MeshResource.primitiveVertices.attributes;
26 meshPack->m_MeshResource.primitiveVertices.attributes = std::make_shared<std::vector<glm::uvec3>>();
27
31 std::vector<glm::vec3> initPoints;
33
38
43 }
44
45 uint32_t meshletStart = 0;
46 const uint32_t maxLod = 0;
47 for (uint32_t lod = 0; lod < maxLod; ++lod)
48 {
49 auto in = std::chrono::high_resolution_clock::now();
50
51 float tLod = lod / (float)maxLod;
52
56 std::vector<Meshlet> meshlets = std::vector<Meshlet>(
57 meshPack->m_MeshResource.meshlets.attributes->begin() + meshletStart,
58 meshPack->m_MeshResource.meshlets.attributes->end()
59 );
60
61 if (meshlets.size() <= 1)
62 {
63 return;
64 }
65
66 const uint32_t nextStart = meshPack->m_MeshResource.meshlets.attributes->size();
67 meshletStart = nextStart;
69
70 for (const auto& group : groups)
71 {
72 std::vector<glm::uvec3> groupPrimVertices;
73 auto ptr = meshPack->m_MeshResource.primitiveVertices.attributes;
74 for (const auto& meshletIndex : group.meshlets)
75 {
76 const auto& meshlet = meshlets[meshletIndex];
77
78 groupPrimVertices.insert(
79 groupPrimVertices.end(),
80 ptr->begin() + meshlet.primitiveOffset,
81 ptr->begin() + meshlet.primitiveOffset + meshlet.nPrimitives
82 );
83 }
84
90
94 std::vector<glm::vec3> points;
96
101
102 float simplifyScale = meshopt_simplifyScale(&points[0].x, points.size(), sizeof(glm::vec3));
103 const float maxDistance = (tLod * 0.01f + (1 - tLod) * 0.001f) * simplifyScale;
104 const float maxUVDistance = tLod * 0.1f + (1 - tLod) * 0.001f;
105 MergeByDistance(meshPack, groupPrimVertices, kdTree, maxDistance, maxUVDistance);
106
110 std::vector<glm::vec3> packPoints;
111 std::vector<glm::uvec3> packPrimPoints;
112 std::unordered_map<uint32_t, uint32_t> primVerticesMapReverse;
114
118 const float threshold = 0.5f;
119 size_t targetCount = packPrimPoints.size() * threshold * 3;
120 float targetError = 0.1f * tLod + 0.01f * (1 - tLod);
121 uint32_t options = meshopt_SimplifyLockBorder;
122
123 std::vector<glm::uvec3> simplifiedPrimPoints(packPrimPoints.size());
124 float simplificationError = 0.0f;
125
126 size_t simplifiedCount = meshopt_simplify(
127 &simplifiedPrimPoints[0].x ,
128 &packPrimPoints[0].x ,
129 packPrimPoints.size() * 3 ,
130 &packPoints[0].x ,
131 packPoints.size() ,
132 sizeof(glm::vec3) ,
133 targetCount ,
134 targetError ,
135 options ,
136 &simplificationError
137 );
138 simplifiedPrimPoints.resize(simplifiedCount / 3);
139
143 std::vector<glm::uvec3> primVerticesBuffer;
145
146 AppendMeshlets(meshPack, lod + 1, clusterBoundSphere, primVerticesBuffer);
147 }
148
149 auto out = std::chrono::high_resolution_clock::now();
150 std::cout << " Lod Cost: " << std::chrono::duration_cast<std::chrono::milliseconds>(out - in).count() << " " << meshlets.size() << std::endl;
151 }
152 }
#define SPICES_PROFILE_ZONE
static bool PackPrimVerticesFromSparseInputs(MeshPack *meshPack, const std::vector< glm::uvec3 > primVertices, std::vector< glm::vec3 > &packPoints, std::vector< glm::uvec3 > &packPrimPoints, std::unordered_map< uint32_t, uint32_t > &primVerticesMapReverse)
Pack PrimVertices from Sparse PrimVertices Inputs.
static SpicesShader::Sphere CalculateBoundSphere(const std::vector< glm::vec3 > &points)
Calculate BoundSphere from Points.
static bool MergeByDistance(MeshPack *meshPack, std::vector< glm::uvec3 > &primVertices, scl::kd_tree< 6 > &kdTree, float maxDistance, float maxUVDistance)
Merge Vertex by Distance.
static bool PackVertexToPoints(MeshPack *meshPack, const std::vector< glm::uvec3 > &primVertices, std::vector< glm::vec3 > &points)
Pack Vertices to Points.
static bool UnPackPrimVerticesToSparseInputs(std::vector< glm::uvec3 > &primVertices, std::unordered_map< uint32_t, uint32_t > &primVerticesMapReverse, const std::vector< glm::uvec3 > &packPrimPoints)
Unpack PrimVertices to Sparse PrimVertices Inputs.
static void AppendMeshlets(MeshPack *meshPack, uint32_t lod, const SpicesShader::Sphere &clusterBoundSphere, const std::vector< glm::uvec3 > &primVertices)
Create and Append Meshlets to MeshPack use given indices.
static std::vector< MeshletGroup > GroupMeshlets(MeshPack *meshPack, std::vector< Meshlet > &meshlets)
Split Meshlets to Groups.
static bool BuildKDTree(MeshPack *meshPack, const std::vector< glm::uvec3 > &primVertices, scl::kd_tree< 6 > &kdTree)
Build KDTree use specific meshlets.
The kd_tree with K dimensions container Class. K the number of dimensions. Every node in the tree is ...