Skip to content

ComputeNormals

Chuck Walbourn edited this page Jan 21, 2022 · 10 revisions
DirectXMesh

Generates vertex normals for a mesh.

HRESULT ComputeNormals(
   const uint16_t* indices, size_t nFaces,
   const XMFLOAT3* positions, size_t nVerts,
   CNORM_FLAGS flags,
   XMFLOAT3* normals );

HRESULT ComputeNormals(
   const uint32_t* indices, size_t nFaces,
   const XMFLOAT3* positions, size_t nVerts,
   CNORM_FLAGS flags,
   XMFLOAT3* normals );

Parameters

flags: A combination of control flags

  • CNORM_DEFAULT is used to compute vertex normals by averaging of the face normals weighted by angle.
  • CNORM_WEIGHT_BY_AREA is used to compute vertex normals by averaging of the face normals weighted by triangle area.
  • CNORM_WEIGHT_EQUAL is used to compute vertex normals by average the face normals with equal weight.
  • CNORM_WIND_CW is used to indicate that the face winding order is clockwise, rather than the default of counter-clockwise winding. This impacts the direction of the generated face normals used in this computation.

Remarks

These functions assume the triangular mesh description is valid. See Validate and Clean

Example

auto mesh = std::make_unique<WaveFrontReader<uint16_t>>();

if ( FAILED( mesh->Load( L"test.obj" ) ) )
   // Error

if ( mesh->hasNormals )
   // Skip next computation

size_t nFaces = mesh->indices.size() / 3;
size_t nVerts = mesh->vertices.size();

auto pos = std::make_unique<XMFLOAT3[]>(nVerts);
for( size_t j = 0; j < nVerts; ++j )
   pos[ j ] = mesh->vertices[ j ].position;

auto normals = std::make_unique<XMFLOAT3[]>(nVerts);
if ( FAILED( ComputeNormals( mesh->indices.data(), nFaces,
   pos.get(), nVerts, CNORM_DEFAULT, normals.get() ) ) )
   // Error

Further Reading

S Jin, R R Lewis, and D West; "A comparison of algorithms for vertex normal computation". link

Nelson Max, "Weights for Computing Vertex Normals from Facet Normals" link

Max Wagner, "Generating Vertex Normals" link