Skip to content

OptimizeFaces

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

Reorders faces to improve post-transform vertex cache reuse using the Hoppe algorithm.

HRESULT OptimizeFaces(
   const uint16_t* indices, size_t nFaces,
   const uint32_t* adjacency,
   uint32_t* faceRemap,
   uint32_t vertexCache = OPTFACES_V_DEFAULT,
   uint32_t restart = OPTFACES_R_DEFAULT );

 HRESULT OptimizeFacesEx(
    const uint16_t* indices, size_t nFaces,
    const uint32_t* adjacency, const uint32_t* attributes,
    uint32_t* faceRemap,
    uint32_t vertexCache = OPTFACES_V_DEFAULT,
    uint32_t restart = OPTFACES_R_DEFAULT );
HRESULT OptimizeFaces(
   const uint32_t* indices, size_t nFaces,
   const uint32_t* adjacency,
   uint32_t* faceRemap,
   uint32_t vertexCache = OPTFACES_V_DEFAULT,
   uint32_t restart = OPTFACES_R_DEFAULT );

HRESULT OptimizeFacesEx(
   const uint32_t* indices, size_t nFaces,
   const uint32_t* adjacency, const uint32_t* attributes,
   uint32_t* faceRemap,
   uint32_t vertexCache = OPTFACES_V_DEFAULT,
   uint32_t restart = OPTFACES_R_DEFAULT );

See also OptimizeFacesLRU

Parameters

faceRemap is an array describing the reordering, and must have nFaces entries: oldLoc = faceRemap[newLoc]. See ReorderIB and ReorderIBAndAdjacency for details.

Note this matches the D3DXMesh::Optimize method and D3DXOptimizeFaces function definitions of the face remap array.

vertexCache is the size of the vertex cache to assume for the optimization. If OPTFACES_STRIPORDER is provided, then the vertex cache simulation is not used and the faces are put in "strip order". This number should typically range from 0 to 32.

restart is a threshold used to control when strips are restarted based. This number must be less than or equal to vertexCache, and is ignored for OPTFACES_STRIPORDER.

Remarks

This implements the same algorithm as D3DX with explicit control over the simulated vertex cache size. OPTFACES_V_DEFAULT / OPTFACES_R_DEFAULT is the same value that D3DXOptimizeFaces used (.e. D3DXMESHOPT_DEVICEINDEPENDENT).

Some vendors support a Direct3D 9 query D3DQUERYTYPE_VCACHE that reports the vertex cache optimization settings that are device specific. If OptMethod is 0, use OPTFACES_STRIPORDER, otherwise pass CacheSize as vertexCache and MagicNumber as restart. For some example code for checking this query, see vcache.cpp.

Note that optimizing for a vertexCache larger than is present on the hardware can result in poorer performance than the original mesh, so this value should be picked either for a known fixed device or conservatively.

Degenerate and 'unused' faces are skipped by the optimization, so they do not appear in the remap order.

There are models where the optimization fails to produce a faster ordering. For this reason, you should evaluate the original and optimized models with ComputeVertexCacheMissRate. If the new model is worse, use the original.

Note that D3DXOptimizeFaces generated adjacency internally, but was low quality as it lacks access to the vertex position. Explicitly generating with GenerateAdjacencyAndPointReps and then optimizing faces is more accurate and provides more programmer control.

Example

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

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

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 adj = std::make_unique<uint32_t[]>(mesh->indices.size());
if ( FAILED( GenerateAdjacencyAndPointReps( mesh->indices.data(), nFaces,
   pos.get(), nVerts, 0.f, nullptr, adj.get() ) ) )
   // Error

auto faceRemap = std::make_unique<uint32_t[]>(nFaces);
if ( FAILED( OptimizeFaces( mesh->indices.data(), nFaces, adj.get(),
   faceRemap.get() ) ) )
   // Error

auto newIndices = std::make_unique<uint16_t[]>(nFaces * 3);
if ( FAILED( ReorderIB( mesh->indices.data(), nFaces, faceRemap.get(),
   newIndices.get() ) ) )
   // Error

Further Reading

Post Transform Cache

Hoppe, H.; "Optimization of mesh locality for transparent vertex caching", ACM SIGGRAPH 1999 Proceedings link

For Use

  • Universal Windows Platform apps
  • Windows desktop apps
  • Windows 11
  • Windows 10
  • Windows 8.1
  • Xbox One
  • Xbox Series X|S
  • Windows Subsystem for Linux

Architecture

  • x86
  • x64
  • ARM64

For Development

  • Visual Studio 2022
  • Visual Studio 2019 (16.11)
  • clang/LLVM v12 - v18
  • GCC 10.5, 11.4, 12.3
  • MinGW 12.2, 13.2
  • CMake 3.20

Related Projects

DirectX Tool Kit for DirectX 11

DirectX Tool Kit for DirectX 12

DirectXTex

DirectXMath

Tools

Test Suite

Content Exporter

DxCapsViewer

See also

DirectX Landing Page

Clone this wiki locally