You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+46Lines changed: 46 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -391,6 +391,50 @@ When referenced vertex indices are not sequential, the index codec will use arou
391
391
392
392
Index buffer codec only supports triangle list topology; when encoding triangle strips or line lists, use `meshopt_encodeIndexSequence`/`meshopt_decodeIndexSequence` instead. This codec typically encodes indices into ~1 byte per index, but compressing the results further with a general purpose compressor can improve the results to 1-3 bits per index.
393
393
394
+
395
+
### Meshlet compression
396
+
397
+
When using mesh shading or clustered raytracing, meshlet vertex reference and triangle data can be compressed similarly to index data. This library provides a dedicated codec that exploits locality inherent in meshlet data. Unlike vertex and index buffer codecs that work on entire buffers, the meshlet codec encodes each meshlet independently; this allows applications to have more flexibility in structuring the runtime storage and adjust the decoded data during decoding. This also means that in some applications, additional data describing the meshlet (vertex/triangle count, encoded size) will need to be encoded into the meshlet stream, if it isn't already available during decoding.
398
+
399
+
The input to the encoder is the vertex index array and micro-index buffer for a single meshlet, as produced by `meshopt_buildMeshlets`. To encode a meshlet, allocate a target buffer using the worst case bound and call the encoding function:
// write m.vertex_count, m.triangle_count, msize and mbuf[0..msize-1] to the output stream
410
+
}
411
+
```
412
+
413
+
To decode the data at runtime, call the decoding function:
414
+
415
+
```c++
416
+
uint16_t* vertices = ...;
417
+
uint8_t* triangles = ...;
418
+
419
+
// automatically deduces `vertex_size=2` and `triangle_size=3` based on pointer types
420
+
int res = meshopt_decodeMeshlet(vertices, m.vertex_count, triangles, m.triangle_count, stream, encoded_size);
421
+
assert(res == 0);
422
+
```
423
+
424
+
Vertex indices can be decoded as 16-bit or 32-bit elements; triangle data can be decoded as byte triplets (3 bytes per triangle, matching the `meshopt_buildMeshlets` output format) or as 32-bit packed elements (4 bytes per triangle, `a | (b << 8) | (c << 16)`). Output buffers must have available space aligned to 4 bytes; for example, decoding a 3-triangle stream using 3 bytes per triangle needs to be able to write 12 bytes to the output triangles array.
425
+
426
+
When using the C++ API, `meshopt_decodeMeshlet` will automatically deduce the element sizes based on the types of vertex and triangle pointers; when using the C API, the sizes need to be specified explicitly.
427
+
428
+
Decoder is heavily optimized and can directly target write-combined memory; you can expect it to run at 7-10 GB/s on modern desktop CPUs.
429
+
430
+
Note that meshlet encoding assumes that the meshlet data was optimized; meshlets should be processed using `meshopt_optimizeMeshlet` before encoding. Additionally, vertex references should have a high degree of reference locality; this can be achieved by building meshlets from meshes optimized for vertex cache/fetch, or linearizing the vertex reference data (and reordering the vertex buffer accordingly). Feeding unoptimized data into the encoder will produce poor compression ratios. Codec preserves the order of triangles, however it can rotate each triangle to improve compression ratio (which means the provoking vertex may change).
431
+
432
+
Meshlets without vertex references are supported; passing `NULL` vertices and `0` vertex count during encoding and decoding will produce encoded meshlets with just triangle data. Note that parameters supplied during decoding must match those used during encoding; if a meshlet was encoded with vertex references, it must be decoded with the same number of vertex references.
433
+
434
+
The meshlet codec targets 5-7 bits per triangle for triangle data; when vertex references are encoded, the encoded size strongly depends on how linear the references are, but it's typical to see 9-12 bits per triangle in aggregate. To reduce the compressed size further, it's possible to compress the resulting encoded data with a general purpose compressor, which usually achieves 5-8 bits/triangle in aggregate; note that in this case general purpose compressors should be applied to a stream with many encoded meshlets at once to amortize their overhead.
435
+
436
+
> Note: this codec is currently experimental and the data format and APIs are subject to change.
437
+
394
438
### Point cloud compression
395
439
396
440
The vertex encoding algorithms can be used to compress arbitrary streams of attribute data; one other use case besides triangle meshes is point cloud data. Typically point clouds come with position, color and possibly other attributes but don't have an implied point order.
@@ -716,6 +760,8 @@ Applications may configure the library to change the attributes of experimental
716
760
Currently, the following APIs are experimental:
717
761
718
762
- `meshopt_SimplifyPermissive` mode for `meshopt_simplify*` functions (and associated `meshopt_SimplifyVertex_*` flags)
763
+
- `meshopt_encodeMeshlet` and `meshopt_encodeMeshletBound` functions
764
+
- `meshopt_decodeMeshlet` and `meshopt_decodeMeshletRaw` functions
* Experimental: Meshlet encoder (work in progress; data format and APIs are subject to change)
299
+
* Experimental: Meshlet encoder
300
+
* Encodes meshlet data into an array of bytes that is generally smaller and compresses better compared to original.
301
+
* Returns encoded data size on success, 0 on error; the only error condition is if buffer doesn't have enough space
302
+
* This function encodes a single meshlet; when encoding multiple meshlets, additional headers may be necessary to store vertex/triangle count and encoded size.
303
+
* For maximum efficiency the meshlet being encoded should be optimized using meshopt_optimizeMeshlet; additionally, vertex reference data should be optimized for locality (fetch).
304
+
*
305
+
* buffer must contain enough space for the encoded meshlet (use meshopt_encodeMeshletBound to compute worst case size)
306
+
* vertices may be NULL, in which case vertex_count must be 0 and only triangle data is encoded
* Decodes meshlet data from an array of bytes generated by meshopt_encodeMeshlet
315
+
* Returns 0 if decoding was successful, and an error code otherwise
316
+
* The decoder is safe to use for untrusted input, but it may produce garbage data.
317
+
*
318
+
* vertices must contain enough space for the resulting vertex data, aligned to 4 bytes (align(vertex_count * vertex_size, 4) bytes)
319
+
* vertex_size must be 2 (16-bit vertex references) or 4 (32-bit vertex references)
320
+
* triangles must contain enough space for the resulting triangle data, aligned to 4 bytes (align(triangle_count * triangle_size, 4) bytes)
321
+
* triangle_size must be 3 (8-bit triangle indices) or 4 (32-bit packed triangles, stored as (a) | (b << 8) | (c << 16))
322
+
* vertex_count, triangle_count match those used during encoding exactly; buffer_size must be equal to the encoded size returned by meshopt_encodeMeshlet.
323
+
* vertices may be NULL, in which case vertex_count must be 0 and the meshlet must contain just triangle data
324
+
*
325
+
* When using "raw" decoding (meshopt_decodeMeshletRaw), both vertices and triangles should have available space further aligned to 16 bytes for efficient SIMD decoding.
0 commit comments