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;
}