Class MeshOptimizer
When a GPU renders triangle meshes, various stages of the GPU pipeline have to process vertex and index data. The efficiency of these stages depends on the data you feed to them; this library provides algorithms to help optimize meshes for these stages, as well as algorithms to reduce the mesh complexity and storage overhead.
Pipeline
When optimizing a mesh, you should typically feed it through a set of optimizations (the order is important!):
- Indexing
- Vertex cache optimization
- Overdraw optimization
- Vertex fetch optimization
- Vertex quantization
- (optional) Vertex/index buffer compression
Indexing
Most algorithms in this library assume that a mesh has a vertex buffer and an index buffer. For algorithms to work well and also for GPU to render your mesh efficiently, the vertex buffer has to have no redundant vertices; you can generate an index buffer from an unindexed vertex buffer or reindex an existing (potentially redundant) index buffer as follows:
First, generate a remap table from your existing vertex (and, optionally, index) data:
size_t index_count = face_count * 3;
std::vector<unsigned int> remap(index_count); // allocate temporary memory for the remap table
size_t vertex_count = meshopt_generateVertexRemap(&remap[0], NULL, index_count, &unindexed_vertices[0], index_count, sizeof(Vertex));
Note that in this case we only have an unindexed vertex buffer; the remap table is generated based on binary equivalence of the input vertices, so the resulting mesh will render the same way.
After generating the remap table, you can allocate space for the target vertex buffer (vertex_count elements) and index buffer
(index_count elements) and generate them:
meshopt_remapIndexBuffer(indices, NULL, index_count, &remap[0]);
meshopt_remapVertexBuffer(vertices, &unindexed_vertices[0], index_count, sizeof(Vertex), &remap[0]);
You can then further optimize the resulting buffers by calling the other functions on them in-place.
Vertex cache optimization
When the GPU renders the mesh, it has to run the vertex shader for each vertex; usually GPUs have a built-in fixed size cache that stores the transformed vertices (the result of running the vertex shader), and uses this cache to reduce the number of vertex shader invocations. This cache is usually small, 16-32 vertices, and can have different replacement policies; to use this cache efficiently, you have to reorder your triangles to maximize the locality of reused vertex references like so:
meshopt_optimizeVertexCache(indices, indices, index_count, vertex_count);
Overdraw optimization
After transforming the vertices, GPU sends the triangles for rasterization which results in generating pixels that are usually first ran through the depth test, and pixels that pass it get the pixel shader executed to generate the final color. As pixel shaders get more expensive, it becomes more and more important to reduce overdraw. While in general improving overdraw requires view-dependent operations, this library provides an algorithm to reorder triangles to minimize the overdraw from all directions, which you should run after vertex cache optimization like this:
meshopt_optimizeOverdraw(indices, indices, index_count, &vertices[0].x, vertex_count, sizeof(Vertex), 1.05f);
The overdraw optimizer needs to read vertex positions as a float3 from the vertex; the code snippet above assumes that the vertex stores
position as float x, y, z.
When performing the overdraw optimization you have to specify a floating-point threshold parameter. The algorithm tries to maintain a balance between vertex cache efficiency and overdraw; the threshold determines how much the algorithm can compromise the vertex cache hit ratio, with 1.05 meaning that the resulting ratio should be at most 5% worse than before the optimization.
Vertex fetch optimization
After the final triangle order has been established, we still can optimize the vertex buffer for memory efficiency. Before running the vertex shader GPU has to fetch the vertex attributes from the vertex buffer; the fetch is usually backed by a memory cache, and as such optimizing the data for the locality of memory access is important. You can do this by running this code:
To optimize the index/vertex buffers for vertex fetch efficiency, call:
meshopt_optimizeVertexFetch(vertices, indices, index_count, vertices, vertex_count, sizeof(Vertex));
This will reorder the vertices in the vertex buffer to try to improve the locality of reference, and rewrite the indices in place to match; if the
vertex data is stored using multiple streams, you should use optimizeVertexFetchRemap instead. This optimization has to be performed on the final
index buffer since the optimal vertex order depends on the triangle order.
Note that the algorithm does not try to model cache replacement precisely and instead just orders vertices in the order of use, which generally produces results that are close to optimal.
Vertex quantization
To optimize memory bandwidth when fetching the vertex data even further, and to reduce the amount of memory required to store the mesh, it is often
beneficial to quantize the vertex attributes to smaller types. While this optimization can technically run at any part of the pipeline (and sometimes
doing quantization as the first step can improve indexing by merging almost identical vertices), it generally is easier to run this after all other
optimizations since some of them require access to float3 positions.
Quantization is usually domain specific; it's common to quantize normals using 3 8-bit integers but you can use higher-precision quantization (for
example using 10 bits per component in a 10_10_10_2 format), or a different encoding to use just 2 components. For positions and texture
coordinate data the two most common storage formats are half precision floats, and 16-bit normalized integers that encode the position relative to the
AABB of the mesh or the UV bounding rectangle.
The number of possible combinations here is very large but this library does provide the building blocks, specifically functions to quantize floating point values to normalized integers, as well as half-precision floats. For example, here's how you can quantize a normal:
unsigned int normal =
(meshopt_quantizeUnorm(v.nx, 10) << 20) |
(meshopt_quantizeUnorm(v.ny, 10) << 10) |
meshopt_quantizeUnorm(v.nz, 10);
and here's how you can quantize a position:
unsigned short px = meshopt_quantizeHalf(v.x);
unsigned short py = meshopt_quantizeHalf(v.y);
unsigned short pz = meshopt_quantizeHalf(v.z);
Vertex/index buffer compression
In case storage size or transmission bandwidth is of importance, you might want to additionally compress vertex and index data. While several mesh compression libraries, like Google Draco, are available, they typically are designed to maximize the compression ratio at the cost of disturbing the vertex/index order (which makes the meshes inefficient to render on GPU) or decompression performance. They also frequently don't support custom game-ready quantized vertex formats and thus require to re-quantize the data after loading it, introducing extra quantization errors and making decoding slower.
Alternatively you can use general purpose compression libraries like zstd or Oodle to compress vertex/index data - however these compressors aren't designed to exploit redundancies in vertex/index data and as such compression rates can be unsatisfactory.
To that end, this library provides algorithms to "encode" vertex and index data. The result of the encoding is generally significantly smaller than initial data, and remains compressible with general purpose compressors - so you can either store encoded data directly (for modest compression ratios and maximum decoding performance), or further compress it with zstd/Oodle to maximize compression ratio.
To encode, you need to allocate target buffers (preferably using the worst case bound) and call encoding functions:
std::vector<unsigned char> vbuf(meshopt_encodeVertexBufferBound(vertex_count, sizeof(Vertex)));
vbuf.resize(meshopt_encodeVertexBuffer(&vbuf[0], vbuf.size(), vertices, vertex_count, sizeof(Vertex)));
std::vector<unsigned char> ibuf(meshopt_encodeIndexBufferBound(index_count, vertex_count));
ibuf.resize(meshopt_encodeIndexBuffer(&ibuf[0], ibuf.size(), indices, index_count));
You can then either serialize vbuf/ibuf as is, or compress them further. To decode the data at runtime, call decoding functions:
int resvb = meshopt_decodeVertexBuffer(vertices, vertex_count, sizeof(Vertex), &vbuf[0], vbuf.size());
int resib = meshopt_decodeIndexBuffer(indices, index_count, &buffer[0], buffer.size());
assert(resvb == 0 && resib == 0);
Note that vertex encoding assumes that vertex buffer was optimized for vertex fetch, and that vertices are quantized; index encoding assumes that the vertex/index buffers were optimized for vertex cache and vertex fetch. Feeding unoptimized data into the encoders will produce poor compression ratios. Both codecs are lossless - the only lossy step is quantization that happens before encoding.
Decoding functions are heavily optimized and can directly target write-combined memory; you can expect both decoders to run at 1-3 GB/s on modern desktop CPUs. Compression ratios depend on the data; vertex data compression ratio is typically around 2-4x (compared to already quantized data), index data compression ratio is around 5-6x (compared to raw 16-bit index data). General purpose lossless compressors can further improve on these results.
Triangle strip conversion
On most hardware, indexed triangle lists are the most efficient way to drive the GPU. However, in some cases triangle strips might prove beneficial:
- On some older GPUs, triangle strips may be a bit more efficient to render
- On extremely memory constrained systems, index buffers for triangle strips could save a bit of memory
This library provides an algorithm for converting a vertex cache optimized triangle list to a triangle strip:
std::vector<unsigned int> strip(meshopt_stripifyBound(index_count));
unsigned int restart_index = ~0u;
size_t strip_size = meshopt_stripify(&strip[0], indices, index_count, vertex_count, restart_index);
Typically you should expect triangle strips to have ~50-60% of indices compared to triangle lists (~1.5-1.8 indices per triangle) and have ~5% worse ACMR. Note that triangle strips can be stitched with or without restart index support. Using restart indices can result in ~10% smaller index buffers, but on some GPUs restart indices may result in decreased performance.
Deinterleaved geometry
All of the examples above assume that geometry is represented as a single vertex buffer and a single index buffer. This requires storing all vertex attributes - position, normal, texture coordinate, skinning weights etc. - in a single contiguous struct. However, in some cases using multiple vertex streams may be preferable. In particular, if some passes require only positional data - such as depth pre-pass or shadow map - then it may be beneficial to split it from the rest of the vertex attributes to make sure the bandwidth use during these passes is optimal. On some mobile GPUs a position-only attribute stream also improves efficiency of tiling algorithms.
Most of the functions in this library either only need the index buffer (such as vertex cache optimization) or only need positional information (such as overdraw optimization). However, several tasks require knowledge about all vertex attributes.
For indexing, generateVertexRemap assumes that there's just one vertex stream; when multiple vertex streams are used, it's necessary to use
generateVertexRemapMulti as follows:
meshopt_Stream streams[] = {
{&unindexed_pos[0], sizeof(float) * 3, sizeof(float) * 3},
{&unindexed_nrm[0], sizeof(float) * 3, sizeof(float) * 3},
{&unindexed_uv[0], sizeof(float) * 2, sizeof(float) * 2},
};
std::vector<unsigned int> remap(index_count);
size_t vertex_count = meshopt_generateVertexRemapMulti(&remap[0], NULL, index_count, index_count, streams, sizeof(streams) / sizeof(streams[0]));
After this remapVertexBuffer needs to be called once for each vertex stream to produce the correctly reindexed stream.
Instead of calling optimizeVertexFetch for reordering vertices in a single vertex buffer for efficiency, calling optimizeVertexFetchRemap and
then calling remapVertexBuffer for each stream again is recommended.
Finally, when compressing vertex data, encodeVertexBuffer should be used on each vertex stream separately - this allows the encoder to best utilize
correlation between attribute values for different vertices.
Simplification
All algorithms presented so far don't affect visual appearance at all, with the exception of quantization that has minimal controlled impact. However, fundamentally the most effective way at reducing the rendering or transmission cost of a mesh is to make the mesh simpler.
This library provides two simplification algorithms that reduce the number of triangles in the mesh. Given a vertex and an index buffer, they generate
a second index buffer that uses existing vertices in the vertex buffer. This index buffer can be used directly for rendering with the original vertex
buffer (preferably after vertex cache optimization), or a new compact vertex/index buffer can be generated using optimizeVertexFetch that uses the
optimal number and order of vertices.
The first simplification algorithm, simplify, follows the topology of the original mesh in an attempt to preserve attribute seams, borders and
overall appearance. For meshes with inconsistent topology or many seams, such as faceted meshes, it can result in simplifier getting "stuck" and not
being able to simplify the mesh fully; it's recommended to preprocess the index buffer with generateShadowIndexBuffer to discard any vertex
attributes that aren't critical and can be rebuilt later such as normals.
float threshold = 0.2f;
size_t target_index_count = size_t(index_count * threshold);
float target_error = 1e-2f;
std::vector<unsigned int> lod(index_count);
lod.resize(meshopt_simplify(&lod[0], indices, index_count, &vertices[0].x, vertex_count, sizeof(Vertex), target_index_count, target_error));
Target error is an approximate measure of the deviation from the original mesh using distance normalized to 0..1 (so 1e-2f means that
simplifier will try to maintain the error to be below 1% of the mesh extents). Note that because of topological restrictions and error bounds
simplifier isn't guaranteed to reach the target index count and can stop earlier.
The second simplification algorithm, simplifySloppy, doesn't follow the topology of the original mesh. This means that it doesn't preserve attribute
seams or borders, but it can collapse internal details that are too small to matter better because it can merge mesh features that are topologically
disjoint but spatially close.
float threshold = 0.2f;
size_t target_index_count = size_t(index_count * threshold);
std::vector<unsigned int> lod(target_index_count);
lod.resize(meshopt_simplifySloppy(&lod[0], indices, index_count, &vertices[0].x, vertex_count, sizeof(Vertex), target_index_count));
This algorithm is guaranteed to return a result at or below the target index count. It is 5-6x faster than simplify when simplification ratio is
large, and is able to reach ~20M triangles/sec on a desktop CPU (meshopt_simplify works at ~3M triangles/sec).
When a sequence of LOD meshes is generated that all use the original vertex buffer, care must be taken to order vertices optimally to not penalize
mobile GPU architectures that are only capable of transforming a sequential vertex buffer range. It's recommended in this case to first optimize each
LOD for vertex cache, then assemble all LODs in one large index buffer starting from the coarsest LOD (the one with fewest triangles), and call
optimizeVertexFetch on the final large index buffer. This will make sure that coarser LODs require a smaller vertex range and are efficient wrt
vertex fetch and transform.
Efficiency analyzers
While the only way to get precise performance data is to measure performance on the target GPU, it can be valuable to measure the impact of these
optimization in a GPU-independent manner. To this end, the library provides analyzers for all three major optimization routines. For each optimization
there is a corresponding analyze function, like analyzeOverdraw, that returns a struct with statistics.
analyzeVertexCache returns vertex cache statistics. The common metric to use is ACMR - average cache miss ratio, which is the ratio of the total
number of vertex invocations to the triangle count. The worst-case ACMR is 3 (GPU has to process 3 vertices for each triangle); on regular grids the
optimal ACMR approaches 0.5. On real meshes it usually is in [0.5..1.5] range depending on the amount of vertex splits. One other useful metric
is ATVR - average transformed vertex ratio - which represents the ratio of vertex shader invocations to the total vertices, and has the best case of
1.0 regardless of mesh topology (each vertex is transformed once).
analyzeVertexFetch returns vertex fetch statistics. The main metric it uses is overfetch - the ratio between the number of bytes read from the
vertex buffer to the total number of bytes in the vertex buffer. Assuming non-redundant vertex buffers, the best case is 1.0 - each byte is fetched
once.
analyzeOverdraw returns overdraw statistics. The main metric it uses is overdraw - the ratio between the number of pixel shader invocations to the
total number of covered pixels, as measured from several different orthographic cameras. The best case for overdraw is 1.0 - each pixel is shaded once.
Note that all analyzers use approximate models for the relevant GPU units, so the numbers you will get as the result are only a rough approximation of the actual performance.
Memory management
Many algorithms allocate temporary memory to store intermediate results or accelerate processing. The amount of memory allocated is a function of
various input parameters such as vertex count and index count. By default memory is allocated using operator new and operator delete;
if these operators are overloaded by the application, the overloads will be used instead. Alternatively it's possible to specify custom
allocation/deallocation functions using setAllocator, e.g.
meshopt_setAllocator(malloc, free);
Note that the library expects the allocation function to either throw in case of out-of-memory (in which case the exception will propagate to the
caller) or abort, so technically the use of malloc above isn't safe. If you want to handle out-of-memory errors without using C++ exceptions,
you can use setjmp/longjmp instead.
Vertex and index decoders (decodeVertexBuffer and decodeIndexBuffer) do not allocate memory and work completely within the buffer space provided
via arguments.
All functions have bounded stack usage that does not exceed 32 KB for any algorithms.
LWJGL note: meshoptimizer can be configured to use the LWJGL memory allocator with the following code:
nmeshopt_setAllocator(
MemoryUtil.getAllocator().getMalloc(),
MemoryUtil.getAllocator().getFree()
);-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intmeshopt_EncodeExpModestatic final intmeshopt_EncodeExpModestatic final intmeshopt_EncodeExpModestatic final intmeshopt_EncodeExpModestatic final intSimplification options.static final intSimplification options.static final intSimplification options.static final intSimplification options.static final int -
Method Summary
Modifier and TypeMethodDescriptionstatic MeshoptOverdrawStatisticsmeshopt_analyzeOverdraw(IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, MeshoptOverdrawStatistics __result) Overdraw analyzer.static MeshoptVertexCacheStatisticsmeshopt_analyzeVertexCache(IntBuffer indices, long vertex_count, int cache_size, int warp_size, int primgroup_size, MeshoptVertexCacheStatistics __result) Vertex transform cache analyzer.static MeshoptVertexFetchStatisticsmeshopt_analyzeVertexFetch(IntBuffer indices, long vertex_count, long vertex_size, MeshoptVertexFetchStatistics __result) Vertex fetch cache analyzer.static longmeshopt_buildMeshlets(MeshoptMeshlet.Buffer meshlets, IntBuffer meshlet_vertices, ByteBuffer meshlet_triangles, IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, long max_vertices, long max_triangles, float cone_weight) Meshlet builder.static longmeshopt_buildMeshletsBound(long index_count, long max_vertices, long max_triangles) SeebuildMeshlets.static longmeshopt_buildMeshletsScan(MeshoptMeshlet.Buffer meshlets, IntBuffer meshlet_vertices, ByteBuffer meshlet_triangles, IntBuffer indices, long vertex_count, long max_vertices, long max_triangles) SeebuildMeshlets.static MeshoptBoundsmeshopt_computeClusterBounds(IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, MeshoptBounds __result) Cluster bounds generator.static MeshoptBoundsmeshopt_computeMeshletBounds(IntBuffer meshlet_vertices, ByteBuffer meshlet_triangles, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, MeshoptBounds __result) SeecomputeClusterBounds.static voidmeshopt_decodeFilterExp(ByteBuffer buffer, long count, long stride) Decodes exponential encoding of floating-point data with 8-bit exponent and 24-bit integer mantissa as2^E*M.static voidmeshopt_decodeFilterExp(IntBuffer buffer, long count, long stride) Decodes exponential encoding of floating-point data with 8-bit exponent and 24-bit integer mantissa as2^E*M.static voidmeshopt_decodeFilterOct(ByteBuffer buffer, long count, long stride) Decodes octahedral encoding of a unit vector with K-bit (K ≤ 16) signed X/Y as an input; Z must store 1.0f.static voidmeshopt_decodeFilterOct(ShortBuffer buffer, long count, long stride) Decodes octahedral encoding of a unit vector with K-bit (K ≤ 16) signed X/Y as an input; Z must store 1.0f.static voidmeshopt_decodeFilterQuat(ByteBuffer buffer, long count, long stride) Decodes 3-component quaternion encoding with K-bit (4 ≤ K ≤ 16) component encoding and a 2-bit component index indicating which component to reconstruct.static voidmeshopt_decodeFilterQuat(ShortBuffer buffer, long count, long stride) Decodes 3-component quaternion encoding with K-bit (4 ≤ K ≤ 16) component encoding and a 2-bit component index indicating which component to reconstruct.static intmeshopt_decodeIndexBuffer(ByteBuffer destination, long index_count, long index_size, ByteBuffer buffer) Index buffer decoder.static intmeshopt_decodeIndexSequence(ByteBuffer destination, long index_count, long index_size, ByteBuffer buffer) Index sequence decoder.static intmeshopt_decodeVertexBuffer(ByteBuffer destination, long vertex_count, long vertex_size, ByteBuffer buffer) Vertex buffer decoder.static floatmeshopt_dequantizeHalf(short h) Reverse quantization of a half-precision (as defined by IEEE-754 fp16) floating point value.static voidmeshopt_encodeFilterExp(ByteBuffer destination, long count, long stride, int bits, FloatBuffer data, int mode) Encodes arbitrary (finite) floating-point data with 8-bit exponent and K-bit integer mantissa (1 ≤ K ≤ 24).static voidmeshopt_encodeFilterExp(IntBuffer destination, long count, long stride, int bits, FloatBuffer data, int mode) Encodes arbitrary (finite) floating-point data with 8-bit exponent and K-bit integer mantissa (1 ≤ K ≤ 24).static voidmeshopt_encodeFilterOct(ByteBuffer destination, long count, long stride, int bits, FloatBuffer data) Encodes unit vectors with K-bit (K ≤ 16) signed X/Y as an output.static voidmeshopt_encodeFilterOct(ShortBuffer destination, long count, long stride, int bits, FloatBuffer data) Encodes unit vectors with K-bit (K ≤ 16) signed X/Y as an output.static voidmeshopt_encodeFilterQuat(ByteBuffer destination, long count, long stride, int bits, FloatBuffer data) Encodes unit quaternions with K-bit (4 ≤ K ≤ 16) component encoding.static voidmeshopt_encodeFilterQuat(ShortBuffer destination, long count, long stride, int bits, FloatBuffer data) Encodes unit quaternions with K-bit (4 ≤ K ≤ 16) component encoding.static longmeshopt_encodeIndexBuffer(ByteBuffer buffer, IntBuffer indices) Index buffer encoder.static longmeshopt_encodeIndexBufferBound(long index_count, long vertex_count) static longmeshopt_encodeIndexSequence(ByteBuffer buffer, IntBuffer indices) Index sequence encoder.static longmeshopt_encodeIndexSequenceBound(long index_count, long vertex_count) static voidmeshopt_encodeIndexVersion(int version) Set index encoder format version.static longmeshopt_encodeVertexBuffer(ByteBuffer buffer, ByteBuffer vertices, long vertex_count, long vertex_size) Vertex buffer encoder.static longmeshopt_encodeVertexBufferBound(long vertex_count, long vertex_size) static voidmeshopt_encodeVertexVersion(int version) Set vertex encoder format version.static voidmeshopt_generateAdjacencyIndexBuffer(IntBuffer destination, IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride) Generate index buffer that can be used as a geometry shader input with triangle adjacency topology.static longmeshopt_generateProvokingIndexBuffer(IntBuffer destination, IntBuffer reorder, IntBuffer indices, long index_count, long vertex_count) Experimental: Generate index buffer that can be used for visibility buffer rendering and returns the size of the reorder table.static voidmeshopt_generateShadowIndexBuffer(IntBuffer destination, IntBuffer indices, ByteBuffer vertices, long vertex_count, long vertex_size, long vertex_stride) Generates index buffer that can be used for more efficient rendering when only a subset of the vertex attributes is necessary.static voidmeshopt_generateShadowIndexBufferMulti(IntBuffer destination, IntBuffer indices, long vertex_count, MeshoptStream.Buffer streams) Generates index buffer that can be used for more efficient rendering when only a subset of the vertex attributes is necessary.static voidmeshopt_generateTessellationIndexBuffer(IntBuffer destination, IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride) Generate index buffer that can be used for PN-AEN tessellation with crack-free displacement.static longmeshopt_generateVertexRemap(IntBuffer destination, @Nullable IntBuffer indices, long index_count, ByteBuffer vertices, long vertex_count, long vertex_size) Generates a vertex remap table from the vertex buffer and an optional index buffer and returns number of unique vertices.static longmeshopt_generateVertexRemapMulti(IntBuffer destination, @Nullable IntBuffer indices, long vertex_count, MeshoptStream.Buffer streams) Generates a vertex remap table from multiple vertex streams and an optional index buffer and returns number of unique vertices.static voidmeshopt_optimizeMeshlet(IntBuffer meshlet_vertices, ByteBuffer meshlet_triangles) Experimental: Meshlet optimizer.static voidmeshopt_optimizeOverdraw(IntBuffer destination, IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, float threshold) Overdraw optimizer.static voidmeshopt_optimizeVertexCache(IntBuffer destination, IntBuffer indices, long vertex_count) Vertex transform cache optimizer.static voidmeshopt_optimizeVertexCacheFifo(IntBuffer destination, IntBuffer indices, long vertex_count, int cache_size) Vertex transform cache optimizer for FIFO caches.static voidmeshopt_optimizeVertexCacheStrip(IntBuffer destination, IntBuffer indices, long vertex_count) Vertex transform cache optimizer for strip-like caches.static longmeshopt_optimizeVertexFetch(ByteBuffer destination, IntBuffer indices, ByteBuffer vertices, long vertex_count, long vertex_size) Vertex fetch cache optimizer.static longmeshopt_optimizeVertexFetchRemap(IntBuffer destination, IntBuffer indices) Vertex fetch cache optimizer.static floatmeshopt_quantizeFloat(float v, int N) Quantizes a float into a floating point value with a limited number of significant mantissa bits, preserving the IEEE-754 fp32 binary representation.static shortmeshopt_quantizeHalf(float v) Quantizes a float into half-precision (as defined by IEEE-754 fp16) floating point value.static intmeshopt_quantizeSnorm(float v, int N) Quantizes a float in[-1..1]range into an N-bit fixed pointsnormvalue.static intmeshopt_quantizeUnorm(float v, int N) Quantizes a float in[0..1]range into an N-bit fixed pointunormvalue.static voidmeshopt_remapIndexBuffer(IntBuffer destination, @Nullable IntBuffer indices, long index_count, IntBuffer remap) Generates index buffer from the source index buffer and remap table generated bygenerateVertexRemap.static voidmeshopt_remapVertexBuffer(ByteBuffer destination, ByteBuffer vertices, long vertex_count, long vertex_size, IntBuffer remap) Generates vertex buffer from the source vertex buffer and remap table generated bygenerateVertexRemap.static voidmeshopt_setAllocator(MeshoptAllocateI allocate, MeshoptDeallocateI deallocate) Set allocation callbacks.static longmeshopt_simplify(IntBuffer destination, IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, long target_index_count, float target_error, int options, @Nullable FloatBuffer result_error) Mesh simplifier.static longmeshopt_simplifyPoints(IntBuffer destination, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, @Nullable FloatBuffer vertex_colors, long vertex_colors_stride, float color_weight, long target_vertex_count) Experimental: Point cloud simplifier.static floatmeshopt_simplifyScale(FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride) Returns the error scaling factor used by the simplifier to convert between absolute and relative extents.static longmeshopt_simplifySloppy(IntBuffer destination, IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, long target_index_count, float target_error, @Nullable FloatBuffer result_error) Experimental: Mesh simplifier (sloppy).static longmeshopt_simplifyWithAttributes(IntBuffer destination, IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, FloatBuffer vertex_attributes, long vertex_attributes_stride, FloatBuffer attribute_weights, @Nullable ByteBuffer vertex_lock, long target_index_count, float target_error, int options, @Nullable FloatBuffer result_error) Experimental: Mesh simplifier with attribute metric.static voidmeshopt_spatialSortRemap(IntBuffer destination, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride) Spatial sorter.static voidmeshopt_spatialSortTriangles(IntBuffer destination, IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride) Experimental: Spatial sorter.static longmeshopt_stripify(IntBuffer destination, IntBuffer indices, long vertex_count, int restart_index) Mesh stripifier.static longmeshopt_stripifyBound(long index_count) static longmeshopt_unstripify(IntBuffer destination, IntBuffer indices, int restart_index) Mesh unstripifier.static longmeshopt_unstripifyBound(long index_count) static voidnmeshopt_analyzeOverdraw(long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride, long __result) Unsafe version of:analyzeOverdrawstatic voidnmeshopt_analyzeVertexCache(long indices, long index_count, long vertex_count, int cache_size, int warp_size, int primgroup_size, long __result) Unsafe version of:analyzeVertexCachestatic voidnmeshopt_analyzeVertexFetch(long indices, long index_count, long vertex_count, long vertex_size, long __result) Unsafe version of:analyzeVertexFetchstatic longnmeshopt_buildMeshlets(long meshlets, long meshlet_vertices, long meshlet_triangles, long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride, long max_vertices, long max_triangles, float cone_weight) Unsafe version of:buildMeshletsstatic longnmeshopt_buildMeshletsScan(long meshlets, long meshlet_vertices, long meshlet_triangles, long indices, long index_count, long vertex_count, long max_vertices, long max_triangles) Unsafe version of:buildMeshletsScanstatic voidnmeshopt_computeClusterBounds(long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride, long __result) Unsafe version of:computeClusterBoundsstatic voidnmeshopt_computeMeshletBounds(long meshlet_vertices, long meshlet_triangles, long triangle_count, long vertex_positions, long vertex_count, long vertex_positions_stride, long __result) Unsafe version of:computeMeshletBoundsstatic voidnmeshopt_decodeFilterExp(long buffer, long count, long stride) Unsafe version of:decodeFilterExpstatic voidnmeshopt_decodeFilterOct(long buffer, long count, long stride) Unsafe version of:decodeFilterOctstatic voidnmeshopt_decodeFilterQuat(long buffer, long count, long stride) Unsafe version of:decodeFilterQuatstatic intnmeshopt_decodeIndexBuffer(long destination, long index_count, long index_size, long buffer, long buffer_size) Unsafe version of:decodeIndexBufferstatic intnmeshopt_decodeIndexSequence(long destination, long index_count, long index_size, long buffer, long buffer_size) Unsafe version of:decodeIndexSequencestatic intnmeshopt_decodeVertexBuffer(long destination, long vertex_count, long vertex_size, long buffer, long buffer_size) Unsafe version of:decodeVertexBufferstatic voidnmeshopt_encodeFilterExp(long destination, long count, long stride, int bits, long data, int mode) Unsafe version of:encodeFilterExpstatic voidnmeshopt_encodeFilterOct(long destination, long count, long stride, int bits, long data) Unsafe version of:encodeFilterOctstatic voidnmeshopt_encodeFilterQuat(long destination, long count, long stride, int bits, long data) Unsafe version of:encodeFilterQuatstatic longnmeshopt_encodeIndexBuffer(long buffer, long buffer_size, long indices, long index_count) Unsafe version of:encodeIndexBufferstatic longnmeshopt_encodeIndexSequence(long buffer, long buffer_size, long indices, long index_count) Unsafe version of:encodeIndexSequencestatic longnmeshopt_encodeVertexBuffer(long buffer, long buffer_size, long vertices, long vertex_count, long vertex_size) Unsafe version of:encodeVertexBufferstatic voidnmeshopt_generateAdjacencyIndexBuffer(long destination, long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride) Unsafe version of:generateAdjacencyIndexBufferstatic longnmeshopt_generateProvokingIndexBuffer(long destination, long reorder, long indices, long index_count, long vertex_count) Unsafe version of:generateProvokingIndexBufferstatic voidnmeshopt_generateShadowIndexBuffer(long destination, long indices, long index_count, long vertices, long vertex_count, long vertex_size, long vertex_stride) Unsafe version of:generateShadowIndexBufferstatic voidnmeshopt_generateShadowIndexBufferMulti(long destination, long indices, long index_count, long vertex_count, long streams, long stream_count) Unsafe version of:generateShadowIndexBufferMultistatic voidnmeshopt_generateTessellationIndexBuffer(long destination, long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride) Unsafe version of:generateTessellationIndexBufferstatic longnmeshopt_generateVertexRemap(long destination, long indices, long index_count, long vertices, long vertex_count, long vertex_size) Unsafe version of:generateVertexRemapstatic longnmeshopt_generateVertexRemapMulti(long destination, long indices, long index_count, long vertex_count, long streams, long stream_count) Unsafe version of:generateVertexRemapMultistatic voidnmeshopt_optimizeMeshlet(long meshlet_vertices, long meshlet_triangles, long triangle_count, long vertex_count) Unsafe version of:optimizeMeshletstatic voidnmeshopt_optimizeOverdraw(long destination, long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride, float threshold) Unsafe version of:optimizeOverdrawstatic voidnmeshopt_optimizeVertexCache(long destination, long indices, long index_count, long vertex_count) Unsafe version of:optimizeVertexCachestatic voidnmeshopt_optimizeVertexCacheFifo(long destination, long indices, long index_count, long vertex_count, int cache_size) Unsafe version of:optimizeVertexCacheFifostatic voidnmeshopt_optimizeVertexCacheStrip(long destination, long indices, long index_count, long vertex_count) Unsafe version of:optimizeVertexCacheStripstatic longnmeshopt_optimizeVertexFetch(long destination, long indices, long index_count, long vertices, long vertex_count, long vertex_size) Unsafe version of:optimizeVertexFetchstatic longnmeshopt_optimizeVertexFetchRemap(long destination, long indices, long index_count, long vertex_count) Unsafe version of:optimizeVertexFetchRemapstatic voidnmeshopt_remapIndexBuffer(long destination, long indices, long index_count, long remap) Unsafe version of:remapIndexBufferstatic voidnmeshopt_remapVertexBuffer(long destination, long vertices, long vertex_count, long vertex_size, long remap) Unsafe version of:remapVertexBufferstatic voidnmeshopt_setAllocator(long allocate, long deallocate) Unsafe version of:setAllocatorstatic longnmeshopt_simplify(long destination, long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride, long target_index_count, float target_error, int options, long result_error) Unsafe version of:simplifystatic longnmeshopt_simplifyPoints(long destination, long vertex_positions, long vertex_count, long vertex_positions_stride, long vertex_colors, long vertex_colors_stride, float color_weight, long target_vertex_count) Unsafe version of:simplifyPointsstatic floatnmeshopt_simplifyScale(long vertex_positions, long vertex_count, long vertex_positions_stride) Unsafe version of:simplifyScalestatic longnmeshopt_simplifySloppy(long destination, long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride, long target_index_count, float target_error, long result_error) Unsafe version of:simplifySloppystatic longnmeshopt_simplifyWithAttributes(long destination, long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride, long vertex_attributes, long vertex_attributes_stride, long attribute_weights, long attribute_count, long vertex_lock, long target_index_count, float target_error, int options, long result_error) Unsafe version of:simplifyWithAttributesstatic voidnmeshopt_spatialSortRemap(long destination, long vertex_positions, long vertex_count, long vertex_positions_stride) Unsafe version of:spatialSortRemapstatic voidnmeshopt_spatialSortTriangles(long destination, long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride) Unsafe version of:spatialSortTrianglesstatic longnmeshopt_stripify(long destination, long indices, long index_count, long vertex_count, int restart_index) Unsafe version of:stripifystatic longnmeshopt_unstripify(long destination, long indices, long index_count, int restart_index) Unsafe version of:unstripify
-
Field Details
-
MESHOPTIMIZER_VERSION
public static final int MESHOPTIMIZER_VERSION- See Also:
-
meshopt_EncodeExpSeparate
public static final int meshopt_EncodeExpSeparatemeshopt_EncodeExpModeEnum values:
EncodeExpSeparate- When encoding exponents, use separate values for each component (maximum quality).EncodeExpSharedVector- When encoding exponents, use shared value for all components of each vector (better compression).EncodeExpSharedComponent- When encoding exponents, use shared value for each component of all vectors (best compression).EncodeExpClamped- Experimental: When encoding exponents, use separate values for each component, but clamp to 0 (good quality if very small values are not important).
- See Also:
-
meshopt_EncodeExpClamped
public static final int meshopt_EncodeExpClampedmeshopt_EncodeExpModeEnum values:
EncodeExpSeparate- When encoding exponents, use separate values for each component (maximum quality).EncodeExpSharedVector- When encoding exponents, use shared value for all components of each vector (better compression).EncodeExpSharedComponent- When encoding exponents, use shared value for each component of all vectors (best compression).EncodeExpClamped- Experimental: When encoding exponents, use separate values for each component, but clamp to 0 (good quality if very small values are not important).
- See Also:
-
meshopt_SimplifyLockBorder
public static final int meshopt_SimplifyLockBorderSimplification options.Enum values:
SimplifyLockBorder- Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle).Useful for simplifying portions of the larger mesh.
SimplifySparse- Improve simplification performance assuming input indices are a sparse subset of the mesh.Note that error becomes relative to subset extents.
SimplifyErrorAbsolute- Treat error limit and resulting error as absolute instead of relative to mesh extents.SimplifyPrune- Experimental: remove disconnected parts of the mesh during simplification incrementally, regardless of the topological restrictions inside components.
- See Also:
-
meshopt_SimplifySparse
public static final int meshopt_SimplifySparseSimplification options.Enum values:
SimplifyLockBorder- Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle).Useful for simplifying portions of the larger mesh.
SimplifySparse- Improve simplification performance assuming input indices are a sparse subset of the mesh.Note that error becomes relative to subset extents.
SimplifyErrorAbsolute- Treat error limit and resulting error as absolute instead of relative to mesh extents.SimplifyPrune- Experimental: remove disconnected parts of the mesh during simplification incrementally, regardless of the topological restrictions inside components.
- See Also:
-
meshopt_SimplifyErrorAbsolute
public static final int meshopt_SimplifyErrorAbsoluteSimplification options.Enum values:
SimplifyLockBorder- Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle).Useful for simplifying portions of the larger mesh.
SimplifySparse- Improve simplification performance assuming input indices are a sparse subset of the mesh.Note that error becomes relative to subset extents.
SimplifyErrorAbsolute- Treat error limit and resulting error as absolute instead of relative to mesh extents.SimplifyPrune- Experimental: remove disconnected parts of the mesh during simplification incrementally, regardless of the topological restrictions inside components.
- See Also:
-
meshopt_SimplifyPrune
public static final int meshopt_SimplifyPruneSimplification options.Enum values:
SimplifyLockBorder- Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle).Useful for simplifying portions of the larger mesh.
SimplifySparse- Improve simplification performance assuming input indices are a sparse subset of the mesh.Note that error becomes relative to subset extents.
SimplifyErrorAbsolute- Treat error limit and resulting error as absolute instead of relative to mesh extents.SimplifyPrune- Experimental: remove disconnected parts of the mesh during simplification incrementally, regardless of the topological restrictions inside components.
- See Also:
-
-
Method Details
-
nmeshopt_generateVertexRemap
public static long nmeshopt_generateVertexRemap(long destination, long indices, long index_count, long vertices, long vertex_count, long vertex_size) Unsafe version of:generateVertexRemap -
meshopt_generateVertexRemap
public static long meshopt_generateVertexRemap(IntBuffer destination, @Nullable IntBuffer indices, long index_count, ByteBuffer vertices, long vertex_count, long vertex_size) Generates a vertex remap table from the vertex buffer and an optional index buffer and returns number of unique vertices.As a result, all vertices that are binary equivalent map to the same (new) location, with no gaps in the resulting sequence. Resulting remap table maps old vertices to new vertices and can be used in
remapVertexBuffer/remapIndexBuffer. Note that binary equivalence considers allvertex_sizebytes, including padding which should be zero-initialized.- Parameters:
destination- must contain enough space for the resulting remap table (vertex_countelements)indices- can beNULLif the input is unindexed
-
nmeshopt_generateVertexRemapMulti
public static long nmeshopt_generateVertexRemapMulti(long destination, long indices, long index_count, long vertex_count, long streams, long stream_count) Unsafe version of:generateVertexRemapMulti- Parameters:
stream_count- must be ≤ 16
-
meshopt_generateVertexRemapMulti
public static long meshopt_generateVertexRemapMulti(IntBuffer destination, @Nullable IntBuffer indices, long vertex_count, MeshoptStream.Buffer streams) Generates a vertex remap table from multiple vertex streams and an optional index buffer and returns number of unique vertices.As a result, all vertices that are binary equivalent map to the same (new) location, with no gaps in the resulting sequence. Resulting remap table maps old vertices to new vertices and can be used in
remapVertexBuffer/remapIndexBuffer. To remap vertex buffers, you will need to callmeshopt_remapVertexBufferfor each vertex stream. Note that binary equivalence considers all size bytes in each stream, including padding which should be zero-initialized.- Parameters:
destination- must contain enough space for the resulting remap table (vertex_countelements)indices- can beNULLif the input is unindexed
-
nmeshopt_remapVertexBuffer
public static void nmeshopt_remapVertexBuffer(long destination, long vertices, long vertex_count, long vertex_size, long remap) Unsafe version of:remapVertexBuffer -
meshopt_remapVertexBuffer
public static void meshopt_remapVertexBuffer(ByteBuffer destination, ByteBuffer vertices, long vertex_count, long vertex_size, IntBuffer remap) Generates vertex buffer from the source vertex buffer and remap table generated bygenerateVertexRemap.- Parameters:
destination- must contain enough space for the resulting vertex buffer (unique_vertex_countelements, returned bymeshopt_generateVertexRemap)vertex_count- should be the initial vertex count and not the value returned bymeshopt_generateVertexRemap
-
nmeshopt_remapIndexBuffer
public static void nmeshopt_remapIndexBuffer(long destination, long indices, long index_count, long remap) Unsafe version of:remapIndexBuffer -
meshopt_remapIndexBuffer
public static void meshopt_remapIndexBuffer(IntBuffer destination, @Nullable IntBuffer indices, long index_count, IntBuffer remap) Generates index buffer from the source index buffer and remap table generated bygenerateVertexRemap.- Parameters:
destination- must contain enough space for the resulting index buffer (index_countelements)indices- can beNULLif the input is unindexed
-
nmeshopt_generateShadowIndexBuffer
public static void nmeshopt_generateShadowIndexBuffer(long destination, long indices, long index_count, long vertices, long vertex_count, long vertex_size, long vertex_stride) Unsafe version of:generateShadowIndexBuffer -
meshopt_generateShadowIndexBuffer
public static void meshopt_generateShadowIndexBuffer(IntBuffer destination, IntBuffer indices, ByteBuffer vertices, long vertex_count, long vertex_size, long vertex_stride) Generates index buffer that can be used for more efficient rendering when only a subset of the vertex attributes is necessary.All vertices that are binary equivalent (wrt first
vertex_sizebytes) map to the first vertex in the original vertex buffer. This makes it possible to use the index buffer for Z pre-pass or shadowmap rendering, while using the original index buffer for regular rendering. Note that binary equivalence considers allvertex_sizebytes, including padding which should be zero-initialized.- Parameters:
destination- must contain enough space for the resulting index buffer (index_countelements)
-
nmeshopt_generateShadowIndexBufferMulti
public static void nmeshopt_generateShadowIndexBufferMulti(long destination, long indices, long index_count, long vertex_count, long streams, long stream_count) Unsafe version of:generateShadowIndexBufferMulti- Parameters:
stream_count- must be ≤ 16
-
meshopt_generateShadowIndexBufferMulti
public static void meshopt_generateShadowIndexBufferMulti(IntBuffer destination, IntBuffer indices, long vertex_count, MeshoptStream.Buffer streams) Generates index buffer that can be used for more efficient rendering when only a subset of the vertex attributes is necessary.All vertices that are binary equivalent (wrt specified
streams) map to the first vertex in the original vertex buffer. This makes it possible to use the index buffer for Z pre-pass or shadowmap rendering, while using the original index buffer for regular rendering. Note that binary equivalence considers all size bytes in each stream, including padding which should be zero-initialized.- Parameters:
destination- must contain enough space for the resulting index buffer (index_countelements)
-
nmeshopt_generateAdjacencyIndexBuffer
public static void nmeshopt_generateAdjacencyIndexBuffer(long destination, long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride) Unsafe version of:generateAdjacencyIndexBuffer -
meshopt_generateAdjacencyIndexBuffer
public static void meshopt_generateAdjacencyIndexBuffer(IntBuffer destination, IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride) Generate index buffer that can be used as a geometry shader input with triangle adjacency topology.Each triangle is converted into a 6-vertex patch with the following layout:
- 0, 2, 4: original triangle vertices
- 1, 3, 5: vertices adjacent to edges 02, 24 and 40
The resulting patch can be rendered with geometry shaders using e.g.
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY. This can be used to implement algorithms like silhouette detection/expansion and other forms of GS-driven rendering.- Parameters:
destination- must contain enough space for the resulting index buffer (index_count*2elements)vertex_positions- should havefloat3position in the first 12 bytes of each vertex
-
nmeshopt_generateTessellationIndexBuffer
public static void nmeshopt_generateTessellationIndexBuffer(long destination, long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride) Unsafe version of:generateTessellationIndexBuffer -
meshopt_generateTessellationIndexBuffer
public static void meshopt_generateTessellationIndexBuffer(IntBuffer destination, IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride) Generate index buffer that can be used for PN-AEN tessellation with crack-free displacement.Each triangle is converted into a 12-vertex patch with the following layout:
- 0, 1, 2: original triangle vertices
- 3, 4: opposing edge for edge 0, 1
- 5, 6: opposing edge for edge 1, 2
- 7, 8: opposing edge for edge 2, 0
- 9, 10, 11: dominant vertices for corners 0, 1, 2
The resulting patch can be rendered with hardware tessellation using PN-AEN and displacement mapping. See "Tessellation on Any Budget" (John McDonald, GDC 2011) for implementation details.
- Parameters:
destination- must contain enough space for the resulting index buffer (index_count*4elements)vertex_positions- should havefloat3position in the first 12 bytes of each vertex
-
nmeshopt_generateProvokingIndexBuffer
public static long nmeshopt_generateProvokingIndexBuffer(long destination, long reorder, long indices, long index_count, long vertex_count) Unsafe version of:generateProvokingIndexBuffer -
meshopt_generateProvokingIndexBuffer
public static long meshopt_generateProvokingIndexBuffer(IntBuffer destination, IntBuffer reorder, IntBuffer indices, long index_count, long vertex_count) Experimental: Generate index buffer that can be used for visibility buffer rendering and returns the size of the reorder table.Each triangle's provoking vertex index is equal to primitive id; this allows passing it to the fragment shader using
nointerpolateattribute. This is important for performance on hardware where primitive id can't be accessed efficiently in fragment shader. The reorder table stores the original vertex id for each vertex in the new index buffer, and should be used in the vertex shader to load vertex data. The provoking vertex is assumed to be the first vertex in the triangle; if this is not the case (OpenGL), rotate each triangle (abc -> bca) before rendering. For maximum efficiency the input index buffer should be optimized for vertex cache first.- Parameters:
destination- must contain enough space for the resulting index buffer (index_countelements)reorder- must contain enough space for the worst case reorder table (vertex_count + index_count / 3elements)
-
nmeshopt_optimizeVertexCache
public static void nmeshopt_optimizeVertexCache(long destination, long indices, long index_count, long vertex_count) Unsafe version of:optimizeVertexCache -
meshopt_optimizeVertexCache
public static void meshopt_optimizeVertexCache(IntBuffer destination, IntBuffer indices, long vertex_count) Vertex transform cache optimizer.Reorders
indicesto reduce the number of GPU vertex shader invocations. If index buffer contains multiple ranges for multiple draw calls, this function needs to be called on each range individually.- Parameters:
destination- must contain enough space for the resulting index buffer (index_countelements)
-
nmeshopt_optimizeVertexCacheStrip
public static void nmeshopt_optimizeVertexCacheStrip(long destination, long indices, long index_count, long vertex_count) Unsafe version of:optimizeVertexCacheStrip -
meshopt_optimizeVertexCacheStrip
public static void meshopt_optimizeVertexCacheStrip(IntBuffer destination, IntBuffer indices, long vertex_count) Vertex transform cache optimizer for strip-like caches.Produces inferior results to
optimizeVertexCachefrom the GPU vertex cache perspective. However, the resulting index order is more optimal if the goal is to reduce the triangle strip length or improve compression efficiency. -
nmeshopt_optimizeVertexCacheFifo
public static void nmeshopt_optimizeVertexCacheFifo(long destination, long indices, long index_count, long vertex_count, int cache_size) Unsafe version of:optimizeVertexCacheFifo -
meshopt_optimizeVertexCacheFifo
public static void meshopt_optimizeVertexCacheFifo(IntBuffer destination, IntBuffer indices, long vertex_count, int cache_size) Vertex transform cache optimizer for FIFO caches.Reorders indices to reduce the number of GPU vertex shader invocations. Generally takes ~3x less time to optimize meshes but produces inferior results compared to
optimizeVertexCache. If index buffer contains multiple ranges for multiple draw calls, this function needs to be called on each range individually.- Parameters:
destination- must contain enough space for the resulting index buffer (index_countelements)cache_size- should be less than the actual GPU cache size to avoid cache thrashing
-
nmeshopt_optimizeOverdraw
public static void nmeshopt_optimizeOverdraw(long destination, long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride, float threshold) Unsafe version of:optimizeOverdraw -
meshopt_optimizeOverdraw
public static void meshopt_optimizeOverdraw(IntBuffer destination, IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, float threshold) Overdraw optimizer.Reorders indices to reduce the number of GPU vertex shader invocations and the pixel overdraw. If index buffer contains multiple ranges for multiple draw calls, this function needs to be called on each range individually.
- Parameters:
destination- must contain enough space for the resulting index buffer (index_countelements)indices- must contain index data that is the result ofoptimizeVertexCache(not the original mesh indices!)vertex_positions- should havefloat3position in the first 12 bytes of each vertexthreshold- indicates how much the overdraw optimizer can degrade vertex cache efficiency (1.05 = up to 5%) to reduce overdraw more efficiently
-
nmeshopt_optimizeVertexFetch
public static long nmeshopt_optimizeVertexFetch(long destination, long indices, long index_count, long vertices, long vertex_count, long vertex_size) Unsafe version of:optimizeVertexFetch -
meshopt_optimizeVertexFetch
public static long meshopt_optimizeVertexFetch(ByteBuffer destination, IntBuffer indices, ByteBuffer vertices, long vertex_count, long vertex_size) Vertex fetch cache optimizer.Reorders vertices and changes indices to reduce the amount of GPU memory fetches during vertex processing. Returns the number of unique vertices, which is the same as input vertex count unless some vertices are unused. This function works for a single vertex stream; for multiple vertex streams, use
optimizeVertexFetchRemap+remapVertexBufferfor each stream.- Parameters:
destination- must contain enough space for the resulting vertex buffer (vertex_countelements)indices- is used both as an input and as an output index buffer
-
nmeshopt_optimizeVertexFetchRemap
public static long nmeshopt_optimizeVertexFetchRemap(long destination, long indices, long index_count, long vertex_count) Unsafe version of:optimizeVertexFetchRemap -
meshopt_optimizeVertexFetchRemap
Vertex fetch cache optimizer.Generates vertex remap to reduce the amount of GPU memory fetches during vertex processing. Returns the number of unique vertices, which is the same as input vertex count unless some vertices are unused. The resulting remap table should be used to reorder vertex/index buffers using
remapVertexBuffer/remapIndexBuffer.- Parameters:
destination- must contain enough space for the resulting remap table (vertex_countelements)
-
nmeshopt_encodeIndexBuffer
public static long nmeshopt_encodeIndexBuffer(long buffer, long buffer_size, long indices, long index_count) Unsafe version of:encodeIndexBuffer -
meshopt_encodeIndexBuffer
Index buffer encoder.Encodes index data into an array of bytes that is generally much smaller (<1.5 bytes/triangle) and compresses better (<1 bytes/triangle) compared to original. Input index buffer must represent a triangle list. Returns encoded data size on success, 0 on error; the only error condition is if buffer doesn't have enough space. For maximum efficiency the index buffer being encoded has to be optimized for vertex cache and vertex fetch first.
- Parameters:
buffer- must contain enough space for the encoded index buffer (useencodeIndexBufferBoundto compute worst case size)
-
meshopt_encodeIndexBufferBound
public static long meshopt_encodeIndexBufferBound(long index_count, long vertex_count) -
meshopt_encodeIndexVersion
public static void meshopt_encodeIndexVersion(int version) Set index encoder format version.- Parameters:
version- must specify the data format version to encode; valid values are 0 (decodable by all library versions) and 1 (decodable by 0.14+)
-
nmeshopt_decodeIndexBuffer
public static int nmeshopt_decodeIndexBuffer(long destination, long index_count, long index_size, long buffer, long buffer_size) Unsafe version of:decodeIndexBuffer -
meshopt_decodeIndexBuffer
public static int meshopt_decodeIndexBuffer(ByteBuffer destination, long index_count, long index_size, ByteBuffer buffer) Index buffer decoder.Decodes index data from an array of bytes generated by
encodeIndexBuffer. Returns 0 if decoding was successful, and an error code otherwise. The decoder is safe to use for untrusted input, but it may produce garbage data (e.g. out of range indices).- Parameters:
destination- must contain enough space for the resulting index buffer (index_countelements)
-
nmeshopt_encodeIndexSequence
public static long nmeshopt_encodeIndexSequence(long buffer, long buffer_size, long indices, long index_count) Unsafe version of:encodeIndexSequence -
meshopt_encodeIndexSequence
Index sequence encoder.Encodes index sequence into an array of bytes that is generally smaller and compresses better compared to original. Input index sequence can represent arbitrary topology; for triangle lists
encodeIndexBufferis likely to be better. Returns encoded data size on success, 0 on error; the only error condition is if buffer doesn't have enough space.- Parameters:
buffer- must contain enough space for the encoded index sequence (useencodeIndexSequenceBoundto compute worst case size)
-
meshopt_encodeIndexSequenceBound
public static long meshopt_encodeIndexSequenceBound(long index_count, long vertex_count) -
nmeshopt_decodeIndexSequence
public static int nmeshopt_decodeIndexSequence(long destination, long index_count, long index_size, long buffer, long buffer_size) Unsafe version of:decodeIndexSequence -
meshopt_decodeIndexSequence
public static int meshopt_decodeIndexSequence(ByteBuffer destination, long index_count, long index_size, ByteBuffer buffer) Index sequence decoder.Decodes index data from an array of bytes generated by
encodeIndexSequence. Returns 0 if decoding was successful, and an error code otherwise. The decoder is safe to use for untrusted input, but it may produce garbage data (e.g. out of range indices).- Parameters:
destination- must contain enough space for the resulting index sequence (index_countelements)
-
nmeshopt_encodeVertexBuffer
public static long nmeshopt_encodeVertexBuffer(long buffer, long buffer_size, long vertices, long vertex_count, long vertex_size) Unsafe version of:encodeVertexBuffer -
meshopt_encodeVertexBuffer
public static long meshopt_encodeVertexBuffer(ByteBuffer buffer, ByteBuffer vertices, long vertex_count, long vertex_size) Vertex buffer encoder.Encodes vertex data into an array of bytes that is generally smaller and compresses better compared to original. Returns encoded data size on success, 0 on error; the only error condition is if buffer doesn't have enough space. This function works for a single vertex stream; for multiple vertex streams, call
meshopt_encodeVertexBufferfor each stream. Note that allvertex_sizebytes of each vertex are encoded verbatim, including padding which should be zero-initialized. For maximum efficiency the vertex buffer being encoded has to be quantized and optimized for locality of reference (cache/fetch) first.- Parameters:
buffer- must contain enough space for the encoded vertex buffer (useencodeVertexBufferBoundto compute worst case size)
-
meshopt_encodeVertexBufferBound
public static long meshopt_encodeVertexBufferBound(long vertex_count, long vertex_size) -
meshopt_encodeVertexVersion
public static void meshopt_encodeVertexVersion(int version) Set vertex encoder format version.- Parameters:
version- must specify the data format version to encode; valid values are 0 (decodable by all library versions)
-
nmeshopt_decodeVertexBuffer
public static int nmeshopt_decodeVertexBuffer(long destination, long vertex_count, long vertex_size, long buffer, long buffer_size) Unsafe version of:decodeVertexBuffer -
meshopt_decodeVertexBuffer
public static int meshopt_decodeVertexBuffer(ByteBuffer destination, long vertex_count, long vertex_size, ByteBuffer buffer) Vertex buffer decoder.Decodes vertex data from an array of bytes generated by
encodeVertexBuffer. Returns 0 if decoding was successful, and an error code otherwise. The decoder is safe to use for untrusted input, but it may produce garbage data.- Parameters:
destination- must contain enough space for the resulting vertex buffer (vertex_count * vertex_sizebytes)
-
nmeshopt_decodeFilterOct
public static void nmeshopt_decodeFilterOct(long buffer, long count, long stride) Unsafe version of:decodeFilterOct -
meshopt_decodeFilterOct
Decodes octahedral encoding of a unit vector with K-bit (K ≤ 16) signed X/Y as an input; Z must store 1.0f.Each component is stored as an 8-bit or 16-bit normalized integer; stride must be equal to 4 or 8. W is preserved as is.
-
meshopt_decodeFilterOct
Decodes octahedral encoding of a unit vector with K-bit (K ≤ 16) signed X/Y as an input; Z must store 1.0f.Each component is stored as an 8-bit or 16-bit normalized integer; stride must be equal to 4 or 8. W is preserved as is.
-
nmeshopt_decodeFilterQuat
public static void nmeshopt_decodeFilterQuat(long buffer, long count, long stride) Unsafe version of:decodeFilterQuat -
meshopt_decodeFilterQuat
Decodes 3-component quaternion encoding with K-bit (4 ≤ K ≤ 16) component encoding and a 2-bit component index indicating which component to reconstruct.Each component is stored as an 16-bit integer; stride must be equal to 8.
-
meshopt_decodeFilterQuat
Decodes 3-component quaternion encoding with K-bit (4 ≤ K ≤ 16) component encoding and a 2-bit component index indicating which component to reconstruct.Each component is stored as an 16-bit integer; stride must be equal to 8.
-
nmeshopt_decodeFilterExp
public static void nmeshopt_decodeFilterExp(long buffer, long count, long stride) Unsafe version of:decodeFilterExp -
meshopt_decodeFilterExp
Decodes exponential encoding of floating-point data with 8-bit exponent and 24-bit integer mantissa as2^E*M.Each 32-bit component is decoded in isolation; stride must be divisible by 4.
-
meshopt_decodeFilterExp
Decodes exponential encoding of floating-point data with 8-bit exponent and 24-bit integer mantissa as2^E*M.Each 32-bit component is decoded in isolation; stride must be divisible by 4.
-
nmeshopt_encodeFilterOct
public static void nmeshopt_encodeFilterOct(long destination, long count, long stride, int bits, long data) Unsafe version of:encodeFilterOct -
meshopt_encodeFilterOct
public static void meshopt_encodeFilterOct(ByteBuffer destination, long count, long stride, int bits, FloatBuffer data) Encodes unit vectors with K-bit (K ≤ 16) signed X/Y as an output.Each component is stored as an 8-bit or 16-bit normalized integer;
stridemust be equal to 4 or 8.Wis preserved as is. Input data must contain 4 floats for every vector (count*4total). -
meshopt_encodeFilterOct
public static void meshopt_encodeFilterOct(ShortBuffer destination, long count, long stride, int bits, FloatBuffer data) Encodes unit vectors with K-bit (K ≤ 16) signed X/Y as an output.Each component is stored as an 8-bit or 16-bit normalized integer;
stridemust be equal to 4 or 8.Wis preserved as is. Input data must contain 4 floats for every vector (count*4total). -
nmeshopt_encodeFilterQuat
public static void nmeshopt_encodeFilterQuat(long destination, long count, long stride, int bits, long data) Unsafe version of:encodeFilterQuat -
meshopt_encodeFilterQuat
public static void meshopt_encodeFilterQuat(ByteBuffer destination, long count, long stride, int bits, FloatBuffer data) Encodes unit quaternions with K-bit (4 ≤ K ≤ 16) component encoding.Each component is stored as an 16-bit integer;
stridemust be equal to 8. Input data must contain 4 floats for every quaternion (count*4total). -
meshopt_encodeFilterQuat
public static void meshopt_encodeFilterQuat(ShortBuffer destination, long count, long stride, int bits, FloatBuffer data) Encodes unit quaternions with K-bit (4 ≤ K ≤ 16) component encoding.Each component is stored as an 16-bit integer;
stridemust be equal to 8. Input data must contain 4 floats for every quaternion (count*4total). -
nmeshopt_encodeFilterExp
public static void nmeshopt_encodeFilterExp(long destination, long count, long stride, int bits, long data, int mode) Unsafe version of:encodeFilterExp -
meshopt_encodeFilterExp
public static void meshopt_encodeFilterExp(ByteBuffer destination, long count, long stride, int bits, FloatBuffer data, int mode) Encodes arbitrary (finite) floating-point data with 8-bit exponent and K-bit integer mantissa (1 ≤ K ≤ 24).Mantissa is shared between all components of a given vector as defined by
stride;stridemust be divisible by 4. Input data must containstride/4floats for every vector (count*stride/4total). When individual (scalar) encoding is desired, simply passstride=4and adjustcountaccordingly. -
meshopt_encodeFilterExp
public static void meshopt_encodeFilterExp(IntBuffer destination, long count, long stride, int bits, FloatBuffer data, int mode) Encodes arbitrary (finite) floating-point data with 8-bit exponent and K-bit integer mantissa (1 ≤ K ≤ 24).Mantissa is shared between all components of a given vector as defined by
stride;stridemust be divisible by 4. Input data must containstride/4floats for every vector (count*stride/4total). When individual (scalar) encoding is desired, simply passstride=4and adjustcountaccordingly. -
nmeshopt_simplify
public static long nmeshopt_simplify(long destination, long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride, long target_index_count, float target_error, int options, long result_error) Unsafe version of:simplify -
meshopt_simplify
public static long meshopt_simplify(IntBuffer destination, IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, long target_index_count, float target_error, int options, @Nullable FloatBuffer result_error) Mesh simplifier. Reduces the number of triangles in the mesh, attempting to preserve mesh appearance as much as possible.The algorithm tries to preserve mesh topology and can stop short of the target goal based on topology constraints or target error. If not all attributes from the input mesh are required, it's recommended to reindex the mesh without them prior to simplification. Returns the number of indices after simplification, with destination containing new index data. The resulting index buffer references vertices from the original vertex buffer. If the original vertex data isn't required, creating a compact vertex buffer using
optimizeVertexFetchis recommended.- Parameters:
destination- must contain enough space for the target index buffer, worst case isindex_countelements (nottarget_index_count)!vertex_positions- should havefloat3position in the first 12 bytes of each vertextarget_error- represents the error relative to mesh extents that can be tolerated, e.g.0.01 = 1% deformation; value range[0..1]options- must be a bitmask composed ofmeshopt_SimplifyXoptions; 0 is a safe defaultresult_error- can beNULL; when it's notNULL, it will contain the resulting (relative) error after simplification
-
nmeshopt_simplifyWithAttributes
public static long nmeshopt_simplifyWithAttributes(long destination, long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride, long vertex_attributes, long vertex_attributes_stride, long attribute_weights, long attribute_count, long vertex_lock, long target_index_count, float target_error, int options, long result_error) Unsafe version of:simplifyWithAttributes- Parameters:
attribute_count- must be ≤ 32
-
meshopt_simplifyWithAttributes
public static long meshopt_simplifyWithAttributes(IntBuffer destination, IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, FloatBuffer vertex_attributes, long vertex_attributes_stride, FloatBuffer attribute_weights, @Nullable ByteBuffer vertex_lock, long target_index_count, float target_error, int options, @Nullable FloatBuffer result_error) Experimental: Mesh simplifier with attribute metric.The algorithm enhances
simplifyby incorporating attribute values into the error metric used to prioritize simplification order; seesimplifyfor details. Note that the number of attributes affects memory requirements and running time; this algorithm requires~1.5xmore memory and time compared tosimplifywhen using 4 scalar attributes.- Parameters:
destination- must contain enough space for the target index buffer, worst case isindex_countelements (nottarget_index_count)!vertex_positions- should havefloat3position in the first 12 bytes of each vertexvertex_attributes- should haveattribute_countfloats for each vertexattribute_weights- should haveattribute_countfloats in total; the weights determine relative priority of attributes between each other and wrt positionvertex_lock- can beNULL; when it's notNULL, it should have a value for each vertex; 1 denotes vertices that can't be movedtarget_error- represents the error relative to mesh extents that can be tolerated, e.g.0.01 = 1% deformation; value range[0..1]options- must be a bitmask composed ofmeshopt_SimplifyXoptions; 0 is a safe defaultresult_error- can beNULL; when it's notNULL, it will contain the resulting (relative) error after simplification
-
nmeshopt_simplifySloppy
public static long nmeshopt_simplifySloppy(long destination, long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride, long target_index_count, float target_error, long result_error) Unsafe version of:simplifySloppy -
meshopt_simplifySloppy
public static long meshopt_simplifySloppy(IntBuffer destination, IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, long target_index_count, float target_error, @Nullable FloatBuffer result_error) Experimental: Mesh simplifier (sloppy). Reduces the number of triangles in the mesh, sacrificing mesh appearance for simplification performance.The algorithm doesn't preserve mesh topology but can stop short of the target goal based on target error. Returns the number of indices after simplification, with destination containing new index data. The resulting index buffer references vertices from the original vertex buffer. If the original vertex data isn't required, creating a compact vertex buffer using
optimizeVertexFetchis recommended.- Parameters:
destination- must contain enough space for the target index buffer, worst case isindex_countelements (nottarget_index_count)!vertex_positions- should havefloat3position in the first 12 bytes of each vertextarget_error- represents the error relative to mesh extents that can be tolerated, e.g.0.01 = 1% deformation; value range[0..1]result_error- can beNULL; when it's notNULL, it will contain the resulting (relative) error after simplification
-
nmeshopt_simplifyPoints
public static long nmeshopt_simplifyPoints(long destination, long vertex_positions, long vertex_count, long vertex_positions_stride, long vertex_colors, long vertex_colors_stride, float color_weight, long target_vertex_count) Unsafe version of:simplifyPoints -
meshopt_simplifyPoints
public static long meshopt_simplifyPoints(IntBuffer destination, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, @Nullable FloatBuffer vertex_colors, long vertex_colors_stride, float color_weight, long target_vertex_count) Experimental: Point cloud simplifier. Reduces the number of points in the cloud to reach the given target.Returns the number of points after simplification, with
destinationcontaining new index data. The resulting index buffer references vertices from the original vertex buffer. If the original vertex data isn't required, creating a compact vertex buffer usingoptimizeVertexFetchis recommended.- Parameters:
destination- must contain enough space for the target index buffer (target_vertex_countelements)vertex_positions- should havefloat3position in the first 12 bytes of each vertexvertex_colors- can beNULL; when it's notNULL, it should havefloat3color in the first 12 bytes of each vertexcolor_weight- determines relative priority of color wrt position; 1.0 is a safe default
-
nmeshopt_simplifyScale
public static float nmeshopt_simplifyScale(long vertex_positions, long vertex_count, long vertex_positions_stride) Unsafe version of:simplifyScale -
meshopt_simplifyScale
public static float meshopt_simplifyScale(FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride) Returns the error scaling factor used by the simplifier to convert between absolute and relative extents.Absolute error must be divided by the scaling factor before passing it to
simplifyastarget_error. Relative error returned bymeshopt_simplifyviaresult_errormust be multiplied by the scaling factor to get absolute error. -
nmeshopt_stripify
public static long nmeshopt_stripify(long destination, long indices, long index_count, long vertex_count, int restart_index) Unsafe version of:stripify -
meshopt_stripify
public static long meshopt_stripify(IntBuffer destination, IntBuffer indices, long vertex_count, int restart_index) Mesh stripifier. Converts a previously vertex cache optimized triangle list to triangle strip, stitching strips using restart index or degenerate triangles.Returns the number of indices in the resulting strip, with destination containing new index data. For maximum efficiency the index buffer being converted has to be optimized for vertex cache first. Using restart indices can result in ~10% smaller index buffers, but on some GPUs restart indices may result in decreased performance.
- Parameters:
destination- must contain enough space for the target index buffer, worst case can be computed withstripifyBoundrestart_index- should be0xffffor0xffffffffdepending on index size, or 0 to use degenerate triangles
-
meshopt_stripifyBound
public static long meshopt_stripifyBound(long index_count) -
nmeshopt_unstripify
public static long nmeshopt_unstripify(long destination, long indices, long index_count, int restart_index) Unsafe version of:unstripify -
meshopt_unstripify
Mesh unstripifier. Converts a triangle strip to a triangle list.Returns the number of indices in the resulting list, with destination containing new index data.
- Parameters:
destination- must contain enough space for the target index buffer, worst case can be computed withunstripifyBound
-
meshopt_unstripifyBound
public static long meshopt_unstripifyBound(long index_count) -
nmeshopt_analyzeVertexCache
public static void nmeshopt_analyzeVertexCache(long indices, long index_count, long vertex_count, int cache_size, int warp_size, int primgroup_size, long __result) Unsafe version of:analyzeVertexCache -
meshopt_analyzeVertexCache
public static MeshoptVertexCacheStatistics meshopt_analyzeVertexCache(IntBuffer indices, long vertex_count, int cache_size, int warp_size, int primgroup_size, MeshoptVertexCacheStatistics __result) Vertex transform cache analyzer.Returns cache hit statistics using a simplified FIFO model. Results may not match actual GPU performance.
-
nmeshopt_analyzeOverdraw
public static void nmeshopt_analyzeOverdraw(long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride, long __result) Unsafe version of:analyzeOverdraw -
meshopt_analyzeOverdraw
public static MeshoptOverdrawStatistics meshopt_analyzeOverdraw(IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, MeshoptOverdrawStatistics __result) Overdraw analyzer. Returns overdraw statistics using a software rasterizer.Results may not match actual GPU performance.
- Parameters:
vertex_positions- should havefloat3position in the first 12 bytes of each vertex
-
nmeshopt_analyzeVertexFetch
public static void nmeshopt_analyzeVertexFetch(long indices, long index_count, long vertex_count, long vertex_size, long __result) Unsafe version of:analyzeVertexFetch -
meshopt_analyzeVertexFetch
public static MeshoptVertexFetchStatistics meshopt_analyzeVertexFetch(IntBuffer indices, long vertex_count, long vertex_size, MeshoptVertexFetchStatistics __result) Vertex fetch cache analyzer. Returns cache hit statistics using a simplified direct mapped model.Results may not match actual GPU performance.
-
nmeshopt_buildMeshlets
public static long nmeshopt_buildMeshlets(long meshlets, long meshlet_vertices, long meshlet_triangles, long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride, long max_vertices, long max_triangles, float cone_weight) Unsafe version of:buildMeshlets -
meshopt_buildMeshlets
public static long meshopt_buildMeshlets(MeshoptMeshlet.Buffer meshlets, IntBuffer meshlet_vertices, ByteBuffer meshlet_triangles, IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, long max_vertices, long max_triangles, float cone_weight) Meshlet builder. Splits the mesh into a set of meshlets where each meshlet has a micro index buffer indexing into meshlet vertices that refer to the original vertex buffer.The resulting data can be used to render meshes using NVidia programmable mesh shading pipeline, or in other cluster-based renderers. When targeting mesh shading hardware, for maximum efficiency meshlets should be further optimized using
optimizeMeshlet. When usingbuildMeshlets, vertex positions need to be provided to minimize the size of the resulting clusters. When usingbuildMeshletsScan, for maximum efficiency the index buffer being converted has to be optimized for vertex cache first.- Parameters:
meshlets- must contain enough space for all meshlets, worst case size can be computed withbuildMeshletsBoundmeshlet_vertices- must contain enough space for all meshlets, worst case size is equal tomax_meshlets * max_verticesmeshlet_triangles- must contain enough space for all meshlets, worst case size is equal tomax_meshlets * max_triangles * 3vertex_positions- should havefloat3position in the first 12 bytes of each vertexmax_vertices- must not exceed implementation limits (max_vertices≤ 255 - not 256!)max_triangles- must not exceed implementation limits (max_triangles≤ 512, must be divisible by 4)cone_weight- should be set to 0 when cone culling is not used, and a value between 0 and 1 otherwise to balance between cluster size and cone culling efficiency
-
nmeshopt_buildMeshletsScan
public static long nmeshopt_buildMeshletsScan(long meshlets, long meshlet_vertices, long meshlet_triangles, long indices, long index_count, long vertex_count, long max_vertices, long max_triangles) Unsafe version of:buildMeshletsScan -
meshopt_buildMeshletsScan
public static long meshopt_buildMeshletsScan(MeshoptMeshlet.Buffer meshlets, IntBuffer meshlet_vertices, ByteBuffer meshlet_triangles, IntBuffer indices, long vertex_count, long max_vertices, long max_triangles) SeebuildMeshlets. -
meshopt_buildMeshletsBound
public static long meshopt_buildMeshletsBound(long index_count, long max_vertices, long max_triangles) SeebuildMeshlets. -
nmeshopt_optimizeMeshlet
public static void nmeshopt_optimizeMeshlet(long meshlet_vertices, long meshlet_triangles, long triangle_count, long vertex_count) Unsafe version of:optimizeMeshlet- Parameters:
triangle_count- must not exceed implementation limits (triangle_count≤ 512)vertex_count- must not exceed implementation limits (vertex_count≤ 255 - not 256!)
-
meshopt_optimizeMeshlet
public static void meshopt_optimizeMeshlet(IntBuffer meshlet_vertices, ByteBuffer meshlet_triangles) Experimental: Meshlet optimizer. Reorders meshlet vertices and triangles to maximize locality to improve rasterizer throughput.When
buildMeshlets*is used, the index data needs to be computed from meshlet'svertex_offsetandtriangle_offset.- Parameters:
meshlet_vertices- must refer to meshlet vertex index datameshlet_triangles- must refer to meshlet triangle index data
-
nmeshopt_computeClusterBounds
public static void nmeshopt_computeClusterBounds(long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride, long __result) Unsafe version of:computeClusterBounds- Parameters:
index_count-index_count / 3must not exceed implementation limits (≤ 512)
-
meshopt_computeClusterBounds
public static MeshoptBounds meshopt_computeClusterBounds(IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, MeshoptBounds __result) Cluster bounds generator. Creates bounding volumes that can be used for frustum, backface and occlusion culling.For backface culling with orthographic projection, use the following formula to reject backfacing clusters:
dot(view, cone_axis) >= cone_cutoffFor perspective projection, you can use the formula that needs cone apex in addition to axis & cutoff:
dot(normalize(cone_apex - camera_position), cone_axis) >= cone_cutoff.Alternatively, you can use the formula that doesn't need cone apex and uses bounding sphere instead:
dot(normalize(center - camera_position), cone_axis) >= cone_cutoff + radius / length(center - camera_position)or an equivalent formula that doesn't have a singularity at center = camera_position:dot(center - camera_position, cone_axis) >= cone_cutoff * length(center - camera_position) + radiusThe formula that uses the apex is slightly more accurate but needs the apex; if you are already using bounding sphere to do frustum/occlusion culling, the formula that doesn't use the apex may be preferable (for derivation see Real-Time Rendering 4th Edition, section 19.3).
- Parameters:
vertex_positions- should havefloat3position in the first 12 bytes of each vertexvertex_count- should specify the number of vertices in the entire mesh, not cluster or meshlet
-
nmeshopt_computeMeshletBounds
public static void nmeshopt_computeMeshletBounds(long meshlet_vertices, long meshlet_triangles, long triangle_count, long vertex_positions, long vertex_count, long vertex_positions_stride, long __result) Unsafe version of:computeMeshletBounds -
meshopt_computeMeshletBounds
public static MeshoptBounds meshopt_computeMeshletBounds(IntBuffer meshlet_vertices, ByteBuffer meshlet_triangles, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride, MeshoptBounds __result) SeecomputeClusterBounds. -
nmeshopt_spatialSortRemap
public static void nmeshopt_spatialSortRemap(long destination, long vertex_positions, long vertex_count, long vertex_positions_stride) Unsafe version of:spatialSortRemap -
meshopt_spatialSortRemap
public static void meshopt_spatialSortRemap(IntBuffer destination, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride) Spatial sorter. Generates a remap table that can be used to reorder points for spatial locality.Resulting remap table maps old vertices to new vertices and can be used in
remapVertexBuffer.- Parameters:
destination- must contain enough space for the resulting remap table (vertex_countelements)vertex_positions- should havefloat3position in the first 12 bytes of each vertex
-
nmeshopt_spatialSortTriangles
public static void nmeshopt_spatialSortTriangles(long destination, long indices, long index_count, long vertex_positions, long vertex_count, long vertex_positions_stride) Unsafe version of:spatialSortTriangles -
meshopt_spatialSortTriangles
public static void meshopt_spatialSortTriangles(IntBuffer destination, IntBuffer indices, FloatBuffer vertex_positions, long vertex_count, long vertex_positions_stride) Experimental: Spatial sorter. Reorders triangles for spatial locality, and generates a new index buffer.The resulting index buffer can be used with other functions like
optimizeVertexCache.- Parameters:
destination- must contain enough space for the resulting index buffer (index_countelements)vertex_positions- should havefloat3position in the first 12 bytes of each vertex
-
nmeshopt_setAllocator
public static void nmeshopt_setAllocator(long allocate, long deallocate) Unsafe version of:setAllocator -
meshopt_setAllocator
Set allocation callbacks.These callbacks will be used instead of the default operator new/operator delete for all temporary allocations in the library. Note that all algorithms only allocate memory for temporary use.
allocate/deallocateare always called in a stack-like order - last pointer to be allocated is deallocated first. -
meshopt_quantizeUnorm
public static int meshopt_quantizeUnorm(float v, int N) Quantizes a float in[0..1]range into an N-bit fixed pointunormvalue.Assumes reconstruction function
q / (2N - 1), which is the case for fixed-function normalized fixed point conversion. Maximum reconstruction error:1 / 2N+1. -
meshopt_quantizeSnorm
public static int meshopt_quantizeSnorm(float v, int N) Quantizes a float in[-1..1]range into an N-bit fixed pointsnormvalue.Assumes reconstruction function
q / (2N-1 - 1), which is the case for fixed-function normalized fixed point conversion (except early OpenGL versions). Maximum reconstruction error:1 / 2N. -
meshopt_quantizeHalf
public static short meshopt_quantizeHalf(float v) Quantizes a float into half-precision (as defined by IEEE-754 fp16) floating point value.Generates
+-inffor overflow, preservesNaN, flushes denormals to zero, rounds to nearest. Representable magnitude range:[6e-5; 65504]. Maximum relative reconstruction error:5e-4. -
meshopt_quantizeFloat
public static float meshopt_quantizeFloat(float v, int N) Quantizes a float into a floating point value with a limited number of significant mantissa bits, preserving the IEEE-754 fp32 binary representation.Generates
+-inffor overflow, preservesNaN, flushes denormals to zero, rounds to nearest. AssumesNis in a valid mantissa precision range, which is1..23. -
meshopt_dequantizeHalf
public static float meshopt_dequantizeHalf(short h) Reverse quantization of a half-precision (as defined by IEEE-754 fp16) floating point value.Preserves Inf/NaN, flushes denormals to zero.
-