//inputs
ALandscape* l = ...
FVector lightDir = ...
#if WITH_EDITOR
for (ULandscapeComponent* c : l->LandscapeComponents)
{
bool canCastShadow = false;
// Checks if any triangle of component can cast shadow from that light direction.
FLandscapeComponentDataInterface CDI(c);
for (int32 y = 0; y < c->ComponentSizeQuads; y++)
{
for (int32 x = 0; x < c->ComponentSizeQuads; x++)
{
FVector center = CDI.GetWorldVertex(x, y);
FVector up = CDI.GetWorldVertex(x, y + 1);
FVector left = CDI.GetWorldVertex(x + 1, y);
FVector upLeft = CDI.GetWorldVertex(x + 1, y + 1);
FVector n0 = FVector::CrossProduct(up - center, center - upLeft);
FVector n1 = FVector::CrossProduct(upLeft - center, center - left);
canCastShadow |= FVector::DotProduct(lightDir, n0) < 0.f;
canCastShadow |= FVector::DotProduct(lightDir, n1) < 0.f;
}
}
c->bCastDynamicShadow = canCastShadow;
}
#endif
This little code snippet checks if landscape components are casting shadows for absolute no reason. In our map 90% of landscape components never contributed to dynamic cascaded shadows but costed hefty amount of performance.
I am now calling this using blueprint but with source code access you can make landscape edit tools to call these kind of optimization functions every time you have finished edits.