#3d #tangent #bevy #graphics #algorithm

no-std bevy_mikktspace

Safe rust implementation of Mikkelsen tangent space algorithm

37 releases

Uses new Rust 2024

0.17.0-dev Aug 3, 2025
0.16.1 May 30, 2025
0.16.0 Apr 24, 2025
0.16.0-rc.3 Mar 31, 2025
0.8.0 Jul 30, 2022

#22 in Graphics APIs

Download history 63539/week @ 2025-09-23 70753/week @ 2025-09-30 66560/week @ 2025-10-07 73058/week @ 2025-10-14 68803/week @ 2025-10-21 59330/week @ 2025-10-28 63673/week @ 2025-11-04 55404/week @ 2025-11-11 61682/week @ 2025-11-18 59200/week @ 2025-11-25 59797/week @ 2025-12-02 70825/week @ 2025-12-09 76296/week @ 2025-12-16 65317/week @ 2025-12-23 60602/week @ 2025-12-30 60047/week @ 2026-01-06

277,123 downloads per month
Used in 1,137 crates (4 directly)

Zlib AND (MIT OR Apache-2.0)

81KB
1K SLoC

Bevy Mikktspace

License Crates.io Downloads Docs Discord

This is a rewrite of the Mikkelsen Tangent Space Algorithm reference implementation in Rust. It is loosely based on mikktspace, an existing port, except bevy_mikktspace has:

  • exact byte-for-byte output equivalence with the original C source under all conditions[^1].
  • fully idiomatic rust with no unsafe code, to support building in no-unsafe contexts.
  • no dependencies, to avoid needing perpetual dependency-version-bump releases in the future.

Requires at least Rust 1.85.1.

Examples

cube_tangents

Demonstrates generating tangents for a cube with 4 triangular faces per side.

cargo run --example cube_tangents

Features

The original reference implementation has a couple bugs, which are largely inconsequential in most practical applications. However, fixing them would mean diverging from exact output equivalence, so bevy_mikktspace offers features to control this behavior:

  • corrected-edge-sorting: Correct a comparison in the reference's edge quicksort implementation. This can only differ on the last triangle in a model.
  • corrected-vertex-welding: Guarantees the smallest-index vertex is chosen when welding. This differs from the reference on NaN vertices.

License agreement

Licensed under either of

at your option. AND parts of the code are licensed under:

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

[^1]: Extensive fuzz-testing against the reference implementation revealed divergence in NaN handling in https://github.com/gltf-rs/mikktspace, which is probably inconsequential for practical uses.

No runtime deps