Problem with cull distance volumes and level streaming

Hi! I have a couple levels that are combined in one level and with level streaming i load that level i want to play. In every level i use one big cull distance volume. Within the editor all works perfect but in the packaged game the cull distance volumes doesn’t work with level streaming. So when i open a level direct without streaming the cull distance volume work proberly but when i stream this level all actors in this level are visable.
So what can i do to fix this in the packaged game? Any hints? I would appreciate any help.

Thanks!

Hey Mike,

Do you have the culling volumes located in your persistent level or in the sub-levels? In my research of your issue I found this post from Reddit that may help you:

You may just need to move your volumes to the persistent level. If that doesn’t work, let me know and we can try something else!

1 Like

Hey Zilphy,
I tried that already and it doesn’t work. Any other idea?
Thx for your help!

Okay, I was able to replicate the issue you were having. I’m not actually sure why this is happening. I’m going to say that this is a bug. I would recommend submitting a bug report for this. A workaround I found worked in my testing was to set distance culling (desired max draw distance) per object and not with a volume. You can find this in the rendering options for the object in the world. I took a screenshot of the setting as well.

What you show above is for lods

After checking the source code, the problem is Cull Distance Volume being triggered only once to iterate all the actor which is visible when persistent level is loaded, this time streaming level may not loaded and being visible(in editor, the streaming level is already loaded and visible if you tick on the Initially Loaded and Initially visible, so it works fine)

the solution is add some tricks in source code

in the LevelTick.cpp, line 1654, customize the code below, and compile the engine

#if WITH_EDITOR
	if(GIsEditor && bDoDelayedUpdateCullDistanceVolumes)
	{
		bDoDelayedUpdateCullDistanceVolumes = false;
		UpdateCullDistanceVolumes();
	}

	//My Custom Code Begin////////////////////////////////////////////////////////
#else

	if (GWorld->HasBegunPlay() && !bDoDelayedUpdateCullDistanceVolumes)
	{
		bDoDelayedUpdateCullDistanceVolumes = true;
		const TArray<ULevelStreaming*>& StreamedLevels = GetWorld()->StreamingLevels;

		for (int32 LevelIndex = 0; LevelIndex < StreamedLevels.Num(); LevelIndex++)
		{
			// Update the level only if it is visible (or not a streamed level)

			if (!StreamedLevels[LevelIndex]->IsLevelVisible())
			{
				//GEngine->AddOnScreenDebugMessage(-1, 60.0f, FColor::Yellow, StreamedLevels[LevelIndex]->GetName());
				bDoDelayedUpdateCullDistanceVolumes = false;
			}
		}

		if (bDoDelayedUpdateCullDistanceVolumes == true)
		{
			UpdateCullDistanceVolumes();
		}

	}

	//My Custom Code End////////////////////////////////////////////////////
#endif // WITH_EDITOR

One last note is about the Cull Distance value setup, the unreal unit is cm, but you may encounter the culling distance not match between PIE and play in packaged game, the problem is the CVar: r.ViewDistanceScale, when you are in Scalability 4, the r.ViewDistanceScale will automatic set to 10. This makes confusing at first if you don’t know what is being control at background.

Thanks SurferHalo! I was having the same problem. I fixed it by adding

World->UpdateCullDistanceVolumes();

to the ULevelStreaming::SetLoadedLevel() method in LevelStreaming.cpp

Hi,
is there a way to change this behaviour with blueprints?

Edit:
I am streaming in a level like the OP, with several Distance Cull Volumes, but they are not taken into account. So can i update them at runtime with blueprints or is this just not common practice? Currently making this for the Quest 2 with Unreal 4.27