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
+47Lines changed: 47 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -796,6 +796,52 @@ Additionally, note that while the code above works with 32-bit OMM indices, afte
796
796
797
797
When using 4-state OMMs, rasterization code produces both unknown-transparent and unknown-opaque states based on microtriangle coverage; this enables the use of forced 2-state flag during traversal for specific effects where micromap data is sufficient for reasonable quality; this is recommended for performance as this results in no any-hit invocations.
798
798
799
+
### Tangent spaces
800
+
801
+
Meshes that use tangent space normal maps often require per-vertex tangent vectors in addition to normals. These could be exported alongside mesh data, but this library also provides an algorithm similar to MikkTSpace that can generate them from positions, normals and texture coordinates:
For each triangle *corner* this writes a normalized tangent vector (xyz) and an orientation sign (+-1); the bitangent can be reconstructed in the shader as `cross(normal, tangent.xyz) * tangent.w`. Note that some coordinate space conventions that flip V direction in the texture space require negating orientation sign. The input can be indexed, as in the example above, or not (`indices=NULL`); this does not affect the output tangents.
810
+
811
+
Because tangents are computed per corner, applying them to mesh vertices requires de-indexing the mesh and generating a new index/vertex buffer afterwards (see `Indexing` section earlier), or using indexed data and copying tangents to existing vertex data while duplicating vertices with different tangents (see `tangents` example in `demo/main.cpp`). With the indexed input, if it contains UV mirroring, vertices along the mirror edge may have different tangent spaces on different sides of the edge and need to be split - copying tangents to existing vertex data without splitting will not produce correct results.
812
+
813
+
If splitting is required, it can be efficiently done with an extra pass and an index list per vertex:
814
+
815
+
```c++
816
+
// seed each vertex with one of its corner tangents; the loop below fixes any mismatches
// walk the chain of split copies looking for a vertex whose tangent matches
825
+
unsigned int v = indices[i];
826
+
while (v != ~0u && vertices[v].tangent != tangents[i])
827
+
v = splits[v];
828
+
829
+
// no match in chain: append a new split copy with the target tangent and chain it
830
+
if (v == ~0u)
831
+
{
832
+
v = unsigned(vertices.size());
833
+
vertices.push_back(vertices[indices[i]]);
834
+
vertices[v].tangent = tangents[i];
835
+
splits.push_back(splits[indices[i]]);
836
+
splits[indices[i]] = v;
837
+
}
838
+
839
+
indices[i] = v;
840
+
}
841
+
```
842
+
843
+
The algorithm uses a MikkTSpace-like construction but by default, uses a modified weighting scheme that significantly improves tangent quality around beveled regions in the mesh. If the normal maps are baked from higher resolution geometry using MikkTSpace weighting, it's possible to produce MikkTSpace-compatible tangents by passing `meshopt_TangentCompatible` option as an extra argument to the function.
844
+
799
845
## Memory management
800
846
801
847
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 `meshopt_setAllocator`, e.g.
@@ -828,6 +874,7 @@ Currently, the following APIs are experimental:
/* Produce tangents compatible with MikkTSpace (same weighting and fallbacks) at the cost of reduced quality. Not recommended unless normal maps are baked. */
907
+
meshopt_TangentCompatible=1 << 0,
908
+
/* Experimental: For vertices only connected to degenerate triangles, output zero tangents instead of an arbitrary fallback. */
909
+
meshopt_TangentZeroFallback=1 << 1,
910
+
};
911
+
901
912
/**
902
913
* Experimental: Tangent space generator
903
-
* Computes per-corner tangent vectors following the MikkTSpace algorithm; for each corner, computes normalized tangent vector (xyz) and orientation (w, +/-1).
914
+
* Computes per-corner tangent vectors; for each corner, computes normalized tangent vector (xyz) and orientation (w, +/-1).
904
915
* Bitangent can be reconstructed via cross(normal, tangent.xyz) * tangent.w.
905
916
* To apply tangents to the mesh, either deindex and reindex it with the tangent stream, or copy tangents to existing vertex data while duplicating
906
917
* vertices with different tangent vectors (e.g. on UV mirror seams).
0 commit comments