npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

mikktspace

v1.1.1

Published

MikkTSpace vertex tangent calculation, in Web Assembly

Downloads

7,670

Readme

mikktspace-wasm

Latest NPM release Build Status

MikkTSpace vertex tangent calculation, in Web Assembly.

A common misunderstanding about tangent space normal maps is that this representation is somehow asset independent. However, normals sampled/captured from a high resolution surface and then transformed into tangent space is more like an encoding. Thus to reverse the original captured field of normals the transformation used to decode would have to be the exact inverse of that which was used to encode.

— Morten S. Mikkelsen

When normal maps render incorrectly, with distortion or unexpectedly inverted insets and extrusions, this misconception may be the cause. Most normal map bakers use the MikkTSpace standard to generate vertex tangents while creating a normal map, and the technique is recommended by the glTF 2.0 specification. Engines reconstructing the tangent space at runtime often use other methods — e.g. derivatives in the pixel shader — for efficiency, when original tangents are not provided. This works well for most assets, but may not work as well for others.

If you have an...

  • Asset that needs to render predictably in many engines
  • Asset Pipeline that needs to produce assets with predictable normal map behavior
  • Engine that needs to support arbitrary assets perfectly (and can afford the per-vertex pre-processing)

...then MikkTSpace vertex tangents may resolve or prevent rendering issues with normal maps.

| correct | incorrect | |---------|-----------| | correct rendering | incorrect rendering |

Figure: Flight Helmet glTF 2.0 sample, shown with correct (left) and incorrect (right) vertex tangents.

Other considerations

The MikkTSpace algorithm requires unindexed (unwelded) triangles as input. It is safe to create an index (welding vertices whose tangents and other attributes are identical) after generating tangents, but you cannot reuse prior indices after generating tangents. This additional cost is, perhaps, why some realtime engines choose to generate tangents with cheaper alternative algorithms, when pre-computed tangents are not provided with the asset.

When generating vertex tangents for glTF 2.0 assets, you will want to flip the sign of the tangents (tangent.w *= -1) before storing them in the glTF file. While MikkTSpace does not document a particular UV convention that I could find, this appears to be a necessary conversion to the texture coordinate convention used in glTF.

Quickstart

Installation:

npm install --save mikktspace

The mikktspace package includes two entrypoints. For modern projects, the default entrypoint uses ES Modules:

import { generateTangents } from 'mikktspace';

const tangents = generateTangents(positions, normals, uvs); // → Float32Array

Node.js does not yet support ES Modules with WebAssembly particularly well (as of Node.js v14), so the mikktspace package also provides a CommonJS entrypoint. The CommonJS entrypoint works only in Node.js.

const { generateTangents } = require('mikktspace');

const tangents = generateTangents(positions, normals, uvs); // → Float32Array

API

generateTangents

Generates vertex tangents for the given position/normal/texcoord attributes. Triangles of the input geometry must be unindexed/unwelded.

Parameters

Returns

Float32Array

Contributing

  1. Install Rust and wasm-pack
  2. Install local dependencies: yarn install
  3. Build: yarn dist
  4. Test: yarn test

Credits

This WebAssembly library is made possible by the gltf-rs/mikktspace project, and by the MikkTSpace standard created by Morten S. Mikkelsen.