Skip to content

Commit 8bc3573

Browse files
js: add clusterizer API - documentation
Documents the new JS clusterizer API in the JS readme.
1 parent 874d201 commit 8bc3573

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

js/README.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,74 @@ The simplification algorithm uses relative errors for input and output; to conve
155155
getScale: (vertex_positions: Float32Array, vertex_positions_stride: number) => number;
156156
```
157157

158+
## Clusterizer
159+
160+
`MeshoptClusterizer` (`meshopt_clusterizer.js`) implements meshlet generation and optimization.
161+
162+
To split a triangle mesh into clusters, call `buildMeshlets`, which tries to balance topological efficiency (by maximizing vertex reuse inside meshlets) with culling efficiency.
163+
164+
```ts
165+
buildMeshlets(indices: Uint32Array, vertex_positions: Float32Array, vertex_positions_stride: number, max_vertices: number, max_triangles: number, cone_weight?: number) => MeshletBuffers;
166+
```
167+
168+
The algorithm uses position data stored in a strided array; `vertex_positions_stride` represents the distance between subsequent positions in `Float32` units.
169+
170+
The maximum number of triangles and number of vertices per meshlet can be controlled via `max_triangles` and `max_vertices` parameters. However, `max_vertices` must not be greater than 255 and `max_triangles` must not be greater than 512.
171+
172+
Additionally, if cluster cone culling is to be used, `buildMeshlets` allows specifying a `cone_weight` as a value between 0 and 1 to balance culling efficiency with other forms of culling. By default, `cone_weight` is set to 0.
173+
174+
All meshlets are implicitly optimized for better triangle and vertex locality by `buildMeshlets`.
175+
176+
The algorithm returns the meshlet data as packed buffers:
177+
178+
```ts
179+
const buffers = MeshoptClusterizer.buildMeshlets(indices, positions, stride, /* args */);
180+
181+
console.log(buffers.meshlets); // prints the raw packed Uint32Array containing the meshlet data, i.e., the indices into the vertices and triangles array
182+
console.log(buffers.vertices); // prints the raw packed Uint32Array containing the indices into the original meshes vertices
183+
console.log(buffers.triangles); // prints the raw packed Uint8Array containing the indices into the verices array.
184+
console.log(buffers.meshletCount); // prints the number of meshlets - this is not the same as buffers.meshlets.length because each meshlet consists of 4 unsigned 32-bit integers
185+
```
186+
187+
Individual meshlets can be extracted from the packed buffers using `extractMeshlet`. The memory of the returned `Meshlet` object's `vertices` and `triangles` arrays is backed by the `MeshletBuffers` object.
188+
189+
```ts
190+
const buffers = MeshoptClusterizer.buildMeshlets(indices, positions, stride, /* args */);
191+
192+
const meshlet = MeshoptClusterizer.extractMeshlet(buffers, 0);
193+
console.log(meshlet.vertices); // prints the packed Uint32Array of the first meshlet's vertex indices, i.e., indices into the original meshes vertex buffer
194+
console.log(meshlet.triangles); // prints the packed Uint8Array of the first meshlet's indices into its own vertices array
195+
196+
console.log(MeshoptClusterizer.extractMeshlet(buffers, 0).triangles[0] === meshlet.triangles[0]) // prints true
197+
198+
meshlet.triangles.set([123], 0);
199+
console.log(MeshoptClusterizer.extractMeshlet(buffers, 0).triangles[0] === meshlet.triangles[0]) // still prints true
200+
```
201+
202+
After generating the meshlet data, it's also possible to generate extra culling data for one or more meshlets:
203+
204+
```ts
205+
computeMeshletBounds(buffers: MeshletBuffers, vertex_positions: Float32Array, vertex_positions_stride: number) => Bounds | Bounds[];
206+
```
207+
208+
If `buffers` contains more than one meshlet, `computeMeshletBounds` returns an array of `Bounds`. Otherwise, a single `Bounds` object is returned.
209+
210+
```ts
211+
const buffers = MeshoptClusterizer.buildMeshlets(indices, positions, stride, /* args */);
212+
const bounds = MeshoptClusterizer.computeMeshletBounds(buffers, positions, stride);
213+
console.log(bounds[0].centerX, bounds[0].centerY, bounds[0].centerZ); // prints the center of the first meshlet's bounding sphere
214+
console.log(bounds[0].radius); // prints the radius of the first meshlet's bounding sphere
215+
console.log(bounds[0].coneApexX, bounds[0].coneApexY, bounds[0].coneApexZ); // prints the apex of the first meshlet's normal cone
216+
console.log(bounds[0].coneAxisX, bounds[0].coneAxisY, bounds[0].coneAxisZ); // prints the axis of the first meshlet's normal cone
217+
console.log(bounds[0].coneCutoff); // prins the cutoff angle of the first meshlet's normal cone
218+
```
219+
220+
It is also possible to compute bounds of a vertex cluster that is not generated by `MeshoptClusterizer` using `computeClusterBounds`. Like `buildMeshlets`, this algorithm takes vertex indices and a strided vertex positions array with a vertex stride in `Float32` units as input.
221+
222+
```ts
223+
computeClusterBounds(indices: Uint32Array, vertex_positions: Float32Array, vertex_positions_stride: number) => Bounds;
224+
```
225+
158226
## License
159227

160228
This library is available to anybody free of charge, under the terms of MIT License (see LICENSE.md).

0 commit comments

Comments
 (0)