r.TriangleOrderOptimization

r.TriangleOrderOptimization

#Overview

name: r.TriangleOrderOptimization

This variable is created as a Console Variable (cvar).

It is referenced in 6 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.TriangleOrderOptimization is to control the algorithm used for optimizing the triangle order for the post-transform cache in Unreal Engine’s rendering system. This setting variable affects how mesh geometry is processed and optimized for rendering performance.

The Unreal Engine subsystems that rely on this setting variable are primarily the mesh utilities and rendering systems. Specifically, it’s used in the MeshBuilderCommon, MeshUtilities, and Engine modules.

The value of this variable is set through the console variable system. It’s defined as a TAutoConsoleVariable in the BuildOptimizationThirdParty namespace, with a default value of 1.

This variable interacts with other variables in the codebase, such as bDisableTriangleOrderOptimization and bUsingNvTriStrip, which are derived from the value of r.TriangleOrderOptimization.

Developers must be aware that changing this variable can affect rendering performance and the correspondence between index buffers and painted vertex colors. It’s particularly important when working with static meshes and their derived data.

Best practices for using this variable include:

  1. Use the default value (1) for most cases, as it uses the Forsyth algorithm, which is described as the fastest option.
  2. Only change to 0 (NVTriStrip) if there’s a specific need for that algorithm.
  3. Avoid setting it to 2 except for debugging purposes, as it disables triangle order optimization entirely.

Regarding the associated variable CVarTriangleOrderOptimization:

This is the actual console variable object that stores the value of r.TriangleOrderOptimization. It’s defined in the BuildOptimizationThirdParty namespace and is used to retrieve the current value of the setting in various parts of the code.

The purpose of CVarTriangleOrderOptimization is to provide a programmatic interface to read and potentially modify the r.TriangleOrderOptimization setting at runtime.

It’s primarily used in the MeshBuilderCommon module, specifically in functions that perform cache optimization on index buffers.

The value of this variable is set when it’s defined, but can be changed at runtime through the console variable system.

Developers should be aware that this variable is used to determine the behavior of mesh optimization functions, and changes to it will immediately affect how these functions operate.

Best practices for using CVarTriangleOrderOptimization include:

  1. Use GetValueOnAnyThread() to read the current value when performing mesh optimizations.
  2. Be cautious about changing its value at runtime, as it could impact performance across the entire engine.
  3. If modifying, ensure that the new value is within the expected range (0, 1, or 2).

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Source/Developer/MeshBuilderCommon/Private/ThirdPartyBuildOptimizationHelper.cpp:16

Scope (from outer to inner):

file
namespace    BuildOptimizationThirdParty

Source code excerpt:

	// CVars
	static TAutoConsoleVariable<int32> CVarTriangleOrderOptimization(
		TEXT("r.TriangleOrderOptimization"),
		1,
		TEXT("Controls the algorithm to use when optimizing the triangle order for the post-transform cache.\n")
		TEXT("0: Use NVTriStrip (slower)\n")
		TEXT("1: Use Forsyth algorithm (fastest)(default)")
		TEXT("2: No triangle order optimization. (least efficient, debugging purposes only)"),
		ECVF_Default);

#Loc: <Workspace>/Engine/Source/Developer/MeshUtilities/Private/MeshUtilities.cpp:5630

Scope (from outer to inner):

file
function     void FMeshUtilities::StartupModule

Source code excerpt:

	PropertyEditorModule.RegisterCustomClassLayout("ProxyLODMeshSimplificationSettings", FOnGetDetailCustomizationInstance::CreateStatic(&FProxyLODMeshSimplificationSettingsCustomization::MakeInstance));

	static const TConsoleVariableData<int32>* CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.TriangleOrderOptimization"));

	bDisableTriangleOrderOptimization = (CVar->GetValueOnGameThread() == 2);

	bUsingNvTriStrip = !bDisableTriangleOrderOptimization && (CVar->GetValueOnGameThread() == 0);

	IMeshReductionManagerModule& Module = FModuleManager::Get().LoadModuleChecked<IMeshReductionManagerModule>("MeshReductionInterface");

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/StaticMesh.cpp:2846

Scope (from outer to inner):

file
function     static FString BuildStaticMeshDerivedDataKeySuffix

Source code excerpt:


	// Value of this CVar affects index buffer <-> painted vertex color correspondence (see UE-51421).
	static const TConsoleVariableData<int32>* CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.TriangleOrderOptimization"));

	// depending on module loading order this might be called too early on Linux (possibly other platforms too?)
	if (CVar == nullptr)
	{
		FModuleManager::Get().LoadModuleChecked<IMeshUtilities>(TEXT("MeshUtilities"));
		CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.TriangleOrderOptimization"));
	}

	if (CVar)
	{
		switch (CVar->GetValueOnAnyThread())
		{

#Associated Variable and Callsites

This variable is associated with another variable named CVarTriangleOrderOptimization. They share the same value. See the following C++ source code.

#Loc: <Workspace>/Engine/Source/Developer/MeshBuilderCommon/Private/ThirdPartyBuildOptimizationHelper.cpp:15

Scope (from outer to inner):

file
namespace    BuildOptimizationThirdParty

Source code excerpt:

{
	// CVars
	static TAutoConsoleVariable<int32> CVarTriangleOrderOptimization(
		TEXT("r.TriangleOrderOptimization"),
		1,
		TEXT("Controls the algorithm to use when optimizing the triangle order for the post-transform cache.\n")
		TEXT("0: Use NVTriStrip (slower)\n")
		TEXT("1: Use Forsyth algorithm (fastest)(default)")
		TEXT("2: No triangle order optimization. (least efficient, debugging purposes only)"),

#Loc: <Workspace>/Engine/Source/Developer/MeshBuilderCommon/Private/ThirdPartyBuildOptimizationHelper.cpp:340

Scope (from outer to inner):

file
namespace    BuildOptimizationThirdParty
function     void CacheOptimizeIndexBuffer

Source code excerpt:

	void CacheOptimizeIndexBuffer(TArray<uint16>& Indices)
	{
		bool bDisableTriangleOrderOptimization = (CVarTriangleOrderOptimization.GetValueOnAnyThread(true) == 2);
		bool bUsingNvTriStrip = !bDisableTriangleOrderOptimization && (CVarTriangleOrderOptimization.GetValueOnAnyThread(true) == 0);

		if (bUsingNvTriStrip)
		{
			NvTriStripHelper::CacheOptimizeIndexBuffer(Indices);
		}
		else if (!bDisableTriangleOrderOptimization)

#Loc: <Workspace>/Engine/Source/Developer/MeshBuilderCommon/Private/ThirdPartyBuildOptimizationHelper.cpp:355

Scope (from outer to inner):

file
namespace    BuildOptimizationThirdParty
function     void CacheOptimizeIndexBuffer

Source code excerpt:

	void CacheOptimizeIndexBuffer(TArray<uint32>& Indices)
	{
		bool bDisableTriangleOrderOptimization = (CVarTriangleOrderOptimization.GetValueOnAnyThread(true) == 2);
		bool bUsingNvTriStrip = !bDisableTriangleOrderOptimization && (CVarTriangleOrderOptimization.GetValueOnAnyThread(true) == 0);

		if (bUsingNvTriStrip)
		{
			NvTriStripHelper::CacheOptimizeIndexBuffer(Indices);
		}
		else if (!bDisableTriangleOrderOptimization)