How do I build correct Landscape HLODs in world partition?

I just edited this out from source engine. Worked without a problem.

void FTextureCompilingManager::AddTextures(TArrayView<UTexture* const> InTextures)
{
	check(IsInGameThread());
	// checkf(bIsRoutingPostCompilation == false,
	// 	TEXT("Registering a texture to the compile manager from inside a texture postcompilation is not supported and usually indicate that the previous async operation wasn't completed (i.e. missing call to PreEditChange) before modifying a texture property."));

	TRACE_CPUPROFILER_EVENT_SCOPE(FTextureCompilingManager::AddTextures)

Because HLOD are submitted to source control only one person needs to do it.

Hi,

I try to build HLODs and it’s building for quite a while but at some pint it crashes with the log mentioning: GPU Payload Timeout

My 4090 and 128GB DDR5 should be beefy enough…
Any ideas?

Build the engine from source, run it with the debugger.
See what is referenced by the error when it happens…

Also, you may want to stress test both your 4090 and RAM to make sure it handles ok.
You never know.

Registering a texture to the compile manager from inside a texture postcompilation is not supported and usually indicate that the previous async operation wasn’t completed (i.e. missing call to PreEditChange) before modifying a texture property.

This github commit is fixing 5.2 VT bug (you need to get github access to UE repository):

https://github.com/EpicGames/UnrealEngine/commit/d1ab4df9a116cb3af8e13c6b76cbc0b996f14ea5

1 Like

dude wtf, oh my god. dude. yoooooooo
men. idk what to say thanks dude. you solved my thing
gg wp

may the gods award you

1 Like

Hey all, I have flagged this problem with the world-building engine team.

The problem stems from the HLODLandscapeBuilder.cpp file. Currently, it calculates the LOD and texture size based on landscape lod 0 resolution and texel density. It results in very dense geo and large textures. Unfortunately, the fix will most likely miss the next hotfix. Until 5.4 releases I have a few workarounds that should resolve the problem.

Source Build
To reduce triangle density on HLOD meshes, increase the LOD 0 Screen Size. I have found a value between 2.2 and 2.7 works well.


Once you have built the HLOD you can set the variables back to default.

The textures will be smaller but you can reduce them further by setting a max texture size to the texture group ‘Hierarchical LOD’.


You can do this in device profiles.

Custom Engine Build
If you have a custom build of the engine from github or perforce you can modify the HLODLandscapeBuilder file to directly set the target resolution and LOD.

5.X\Engine\Source\Runtime\Landscape\Private\LandscapeHLODBuilder.cpp
This directly sets the texture size to 256.

	double TexelRatio = 1;

	// Compute the perfect texture size that would get us to our texture density
	// Also compute the nearest power of two sizes (below and above our target)
	const int32 SizePerfect = 256;
	const int32 SizeHi = 256;
	const int32 SizeLo = 256;

	// Compute the texel density we achieve with these two texture sizes
	const double TexelDensityLo = SizeLo * TexelRatio;
	const double TexelDensityHi = SizeHi * TexelRatio;

	// Select best match between low & high res textures.
	const double TexelDensityLoDiff = InTargetTexelDensity - TexelDensityLo;
	const double TexelDensityHiDiff = TexelDensityHi - InTargetTexelDensity;
	const int32 BestTextureSize = TexelDensityLoDiff < TexelDensityHiDiff ? SizeLo : SizeHi;

	return BestTextureSize;

and you can override the desired target lod to be a higher one rather than 0.

	// These constants are showing up a lot in the screen size computation for Level HLODs. This should be configurable per project.
	const float HalfFOV = PI * 0.25f;
	const float ScreenWidth = 1920.0f;
	const float ScreenHeight = 1080.0f;
	const FPerspectiveMatrix ProjMatrix(HalfFOV, ScreenWidth, ScreenHeight, 1.0f);

	TArray<float> LODScreenSizes = InLandscapeProxy->GetLODScreenSizeArray();

	const ULandscapeComponent* LSComponent = InLandscapeProxy->LandscapeComponents[0];
	const float ComponentRadiusScaled = static_cast<float>(LSComponent->GetLocalBounds().SphereRadius * LSComponent->GetComponentTransform().GetScale3D().GetAbsMax());
	const float ExpectedScreenSize = ComputeBoundsScreenSize(FVector::ZeroVector, ComponentRadiusScaled, FVector(0.0f, 0.0f, InViewDistance), ProjMatrix);

	int32 RequiredLOD;
	for (RequiredLOD = 5; RequiredLOD < LODScreenSizes.Num(); ++RequiredLOD)
	{
		if (ExpectedScreenSize > LODScreenSizes[RequiredLOD])
		{
			break;
		}
	}

	return RequiredLOD;
}
1 Like

Hi, I found this article and I have problems in building HLOD, I wanted to ask for advice. I have a 16x16 level i.e. 256km2, in WP, a lot of foliage in nanite ad I lightened a lot, the problem is that to optimize I created 51200 cells so about 500m2, so in the distance it doesn’t load neither landscape nor foliage. First of all I fail the HLOD build if I don’t remove virtual textures (which I currently don’t use for landscape or landscape materials) and then reactivate it later, plus I realized that as a method HLOD succeeds to build me only in “instancing” mode, here I ask for advice: what is the best mode in your opinion given my situation? I use UE 5.21. On a UE video tutorial the narrator said that the mode that the “Approximated Mesh” mode is for nanites, but he didn’t explain how, basically I am looking for advice. Thank you.

In Unreal Engine 5.3 there is no LandscapeHLODBuilder i don’t have any custom Builder Classes. How would i fix that?

Hello, follow your step, i can not find “LandscapeHLODBuilder” in my new HLOD Layer at UE 5.4.1.
The Layer makes my project always Build Hold With Error, that say about “has an invalid HLOD layer”.
Can you help me fix it ?

Here are my findings with 5.4.1 VT needs to be enabled or you get the below out of memory error because it doesn’t mater what matieral you have set in your HLOD layer it still uses a VT one, so they fixed the error when building HLODs when VT was on but now people can’t build HLODs without it being enabled, the question is can they ever get it right lol.

LogWindows: Error: appError called: Fatal error: [File:F:\Epic Games\UnrealEngine-5.4.1-release\Engine\Source\Runtime\D3D12RHI\Private\D3D12Util.cpp] [Line: 926] 
Out of video memory trying to allocate a rendering resource

In 5.3 and later, the LandscapeHLODBuilder class isn’t directly assignable in-editor. It’s in the engine, and the engine just uses it automatically for the first HLOD layer built from landscape.

It also ignores every single setting in the HLOD Layer Settings, so no matter what HLOD Layer you assign as the world default or directly assign to the Landscape Streaming Proxies it will build that first layer the same way every time. The documentation for this is terrible.