ShowFlag.VisualizeVirtualTexture in build

Hi,

Following this post [Content removed]

I am able to confirm pre-roll during cutscenes is now functional and what I unfortunately see is no matter the amount of pre-roll frames, some textures are still rendered with higher mips after camera cuts. At first sight it looks that the pre-roll doesn’t help, but it rather looks like the virtual texture system does not stream the required mips.

Taking a look at residency everything looks under budget, I would like to use ShowFlag.VisualizeVirtualTexture 1 and r.vt.visualize pending in a build however these look like they need an ODSC server.

Do you know how I can create an ODSC server ? I see that on the cooked build I could specify -odschost=127.0.0.1 for instance ?

Thanks in advance,

Hugo

[Attachment Removed]

Hello,

I apologize for the long delay in response. I just wanted to check in with you on the status of your request. Do you still need assistance with setting up the ODSC server? We don’t have any official docs to point you to right now, but we’re working on publishing a setup guide soon. But the summary to get ODSC up and running is as follows:

  1. Get a staged build (or cook it yourself)
  2. Build both editor and client targets (the odsc server uses the editor executable)
  3. Launch the odsc server via the commandlet that I will paste below:
    1. Large projects may take a while to start because the server needs to scan assets.
    2. When the server is ready, it will display the message Unreal Network File Server is ready for client connections on [ip-of-your-pc]:41899
  4. Run the game with -odschost=[ip-of-your-pc]

This is a commandlet example for running the City Sample project on UE5-Main. Adjust the options as necessary:

<Engine-Directory>\UE5-Main\Engine\Binaries\Win64\UnrealEditor-Cmd.exe <Engine-Directory>\UE5-Main\Samples\Showcases\CitySample\CitySample.uproject -run=cook -odsc -targetplatform=Windows -cookcultures=en -unversioned -stdout -cookonthefly -dpcvars=r.ShaderDevelopmentMode=1Feel free to let me know if there is anything else I can help you with.

Best,

Tim

[Attachment Removed]

Hi Hugo,

This does not look like a known issue, and it seems more like an engine bug than a problem with your ODSC setup. My theory is that the visualization shaders behind the ShowFlag.VisualizeVirtualTexture flag are excluded from cooked data and are only ever compiled on demand through ODSC. When you toggle the show flag, the renderer rebuilds all cached mesh draw commands with the debug shader permutation. For regular meshes, a missing shader is tolerated, and the mesh skips drawing until the ODSC server delivers the compiled shader, whereas for Nanite, this is not possible.

Two ways to keep moving in the meantime. If your problem textures are on non-Nanite geometry (or you can temporarily live without Nanite), launch with -dpcvars=r.Nanite=0, so no Nanite scene proxies are created; the visualization should then work without further issues.

Otherwise, since you are building from source, can you test a small change for me to check if we can skip the compilation request? I pasted the diff below for NaniteShading.cpp:

--- a/Engine/Source/Runtime/Renderer/Private/Nanite/NaniteShading.cpp
+++ b/Engine/Source/Runtime/Renderer/Private/Nanite/NaniteShading.cpp
[Content removed]7 @@
 	const bool bUseWorkGraphShaders = UseWorkGraphForShadingBundles(Scene.GetShaderPlatform());
 	TShaderRef<TBasePassComputeShaderPolicyParamType<FUniformLightMapPolicy>> BasePassShader;
 
-	auto LoadShadingMaterial = [&](const FMaterialRenderProxy* MaterialProxyPtr)
+	auto LoadShadingMaterial = [&](const FMaterialRenderProxy* MaterialProxyPtr, bool bWithDebug)
 	{
 		const FMaterial& ShadingMaterial = MaterialProxy->GetIncompleteMaterialWithFallback(FeatureLevel);
 		check(Nanite::IsSupportedMaterialDomain(ShadingMaterial.GetMaterialDomain()));
[Content removed]7 @@
 				FUniformLightMapPolicy(LightMapPolicyType),
 				FeatureLevel,
 				bRenderSkylight,
-				Scene.RequiresDebugMaterials(),
+				bWithDebug,
 				bUseWorkGraphShaders ? SF_WorkGraphComputeNode : SF_Compute,
 				&BasePassShader
 				);
[Content removed]20 @@
 		return bShadersValid;
 	};
 
-	bool bLoaded = LoadShadingMaterial(MaterialProxy);
+	const bool bIsDebug = Scene.RequiresDebugMaterials();
+	bool bLoaded = LoadShadingMaterial(MaterialProxy, bIsDebug);
+	if (!bLoaded && bIsDebug)
+	{
+		bLoaded = LoadShadingMaterial(MaterialProxy, false);
+	}
 	if (!bLoaded)
 	{
 		MaterialProxy = UMaterial::GetDefaultMaterial(MD_Surface)->GetRenderProxy();
-		bLoaded = LoadShadingMaterial(MaterialProxy);
+		bLoaded = LoadShadingMaterial(MaterialProxy, bIsDebug);
+		if (!bLoaded && bIsDebug)
+		{
+			bLoaded = LoadShadingMaterial(MaterialProxy, false);
+		}
 	}

Let me know if that helps,

Tim

[Attachment Removed]

Hi Hugo,

Thanks for testing out the change. Yes, I do intend to submit this patch to fix up the debug views. Since you tested the patch and confirmed it works, it should allow me to accelerate the review and approval of the changes. Feel free to keep the patch in your build for now, until I can officially submit the changes.

Cheers,

Tim

[Attachment Removed]

Hi Tim,

No worries.

Giving this a try, I instantly encounter this crash when enabling ShowFlag.VisualizeVirtualTexture 1.

Interestingly, I don’t reproduce this crash in a level without any nanite static meshes.

Is this a known issue ?

>	!BuildNaniteMaterialBins(FScene * Scene, FPrimitiveSceneInfo * PrimitiveSceneInfo, bool bLumenEnabled, FNaniteMaterialListContext & MaterialListContext) Line 907	C++
 	[Inline Frame] !FPrimitiveSceneInfo::CacheNaniteMaterialBins::__l11::<lambda>(FNaniteMaterialListContext &) Line 786	C++
 	[Inline Frame] !ParallelForImpl::CallBody(const FPrimitiveSceneInfo::CacheNaniteMaterialBins::__l11::void <lambda>(const TArray<FString,TSizedDefaultAllocator<32>> &, UWorld *, FOutputDevice &) &) Line 74	C++
 	!`ParallelForImpl::ParallelForInternal<`FPrimitiveSceneInfo::CacheNaniteMaterialBins'::`11'::void <lambda>(const TArray<FString,TSizedDefaultAllocator<32>> &, UWorld *, FOutputDevice &),`ParallelForWithTaskContext<FNaniteMaterialListContext,TSizedInlineAllocator<8,32,TSizedDefaultAllocator<32>>,`FPrimitiveSceneInfo::CacheNaniteMaterialBins'::`11'::void <lambda>(const TArray<FString,TSizedDefaultAllocator<32>> &, UWorld *, FOutputDevice &)>'::`5'::void <lambda>(const TArray<FString,TSizedDefaultAllocator<32>> &, UWorld *, FOutputDevice &),FNaniteMaterialListContext>'::`2'::FParallelExecutor::operator()(const bool bIsMaster) Line 360	C++
 	[Inline Frame] !LowLevelTasks::FTask::Init::__l13::<lambda>(const bool) Line 499	C++
 	[Inline Frame] !Invoke(LowLevelTasks::FTask::Init::__l13::void <lambda>(const TArray<FString,TSizedDefaultAllocator<32>> &, UWorld *, FOutputDevice &) &) Line 47	C++
 	[Inline Frame] !LowLevelTasks::TTaskDelegate<LowLevelTasks::FTask * __cdecl(bool),48>::TTaskDelegateImpl<`LowLevelTasks::FTask::Init<`ParallelForImpl::ParallelForInternal<`FPrimitiveSceneInfo::CacheNaniteMaterialBins'::`11'::void <lambda>(const TArray<FString,TSizedDefaultAllocator<32>> &, UWorld *, FOutputDevice &),`ParallelForWithTaskContext<FNaniteMaterialListContext,TSizedInlineAllocator<8,32,TSizedDefaultAllocator<32>>,`FPrimitiveSceneInfo::CacheNaniteMaterialBins'::`11'::void <lambda>(const TArray<FString,TSizedDefaultAllocator<32>> &, UWorld *, FOutputDevice &)>'::`5'::void <lambda>(const TArray<FString,TSizedDefaultAllocator<32>> &, UWorld *, FOutputDevice &),FNaniteMaterialListContext>'::`2'::FParallelExecutor>'::`13'::void <lambda>(const TArray<FString,TSizedDefaultAllocator<32>> &, UWorld *, FOutputDevice &),0>::Call(void *) Line 162	C++
 	!LowLevelTasks::TTaskDelegate<LowLevelTasks::FTask * __cdecl(bool),48>::TTaskDelegateImpl<`LowLevelTasks::FTask::Init<`ParallelForImpl::ParallelForInternal<`FPrimitiveSceneInfo::CacheNaniteMaterialBins'::`11'::void <lambda>(const TArray<FString,TSizedDefaultAllocator<32>> &, UWorld *, FOutputDevice &),`ParallelForWithTaskContext<FNaniteMaterialListContext,TSizedInlineAllocator<8,32,TSizedDefaultAllocator<32>>,`FPrimitiveSceneInfo::CacheNaniteMaterialBins'::`11'::void <lambda>(const TArray<FString,TSizedDefaultAllocator<32>> &, UWorld *, FOutputDevice &)>'::`5'::void <lambda>(const TArray<FString,TSizedDefaultAllocator<32>> &, UWorld *, FOutputDevice &),FNaniteMaterialListContext>'::`2'::FParallelExecutor>'::`13'::void <lambda>(const TArray<FString,TSizedDefaultAllocator<32>> &, UWorld *, FOutputDevice &),0>::CallAndMove(LowLevelTasks::TTaskDelegate<LowLevelTasks::FTask * __cdecl(bool),48> & Destination, void * InlineData, unsigned int DestInlineSize, bool <Params_0>) Line 171	C++
 	[Inline Frame] !LowLevelTasks::TTaskDelegate<LowLevelTasks::FTask * __cdecl(bool),48>::CallAndMove(LowLevelTasks::TTaskDelegate<LowLevelTasks::FTask * __cdecl(bool),48> &) Line 309	C++
 	!LowLevelTasks::FTask::ExecuteTask() Line 627	C++
 	[Inline Frame] !FCpuProfilerTrace::FEventScope::{ctor}(unsigned int &) Line 222	C++
 	!LowLevelTasks::FScheduler::ExecuteTask(LowLevelTasks::FTask * InTask) Line 364	C++
 	[Inline Frame] !LowLevelTasks::FScheduler::TryExecuteTaskFrom(LowLevelTasks::Private::FWaitEvent *) Line 665	C++
 	!LowLevelTasks::FScheduler::WorkerLoop(LowLevelTasks::Private::FWaitEvent * WorkerEvent, LowLevelTasks::Private::TLocalQueueRegistry<1024,1024>::TLocalQueue * WorkerLocalQueue, unsigned int WaitCycles, bool bPermitBackgroundWork) Line 724	C++
 	[Inline Frame] !LowLevelTasks::FScheduler::WorkerMain(LowLevelTasks::Private::FWaitEvent * WorkerEvent, LowLevelTasks::Private::TLocalQueueRegistry<1024,1024>::TLocalQueue * WorkerLocalQueue, unsigned int WaitCycles, bool) Line 783	C++
 	!LowLevelTasks::FScheduler::CreateWorker::__l2::<lambda>() Line 188	C++
 	[Inline Frame] !UE::Core::Private::Function::TFunctionRefBase<UE::Core::Private::Function::TFunctionStorage<1>,void __cdecl(void)>::operator()() Line 471	C++
 	!FThreadImpl::Run() Line 69	C++
 	!FRunnableThreadWin::Run() Line 159	C++
 	!FRunnableThreadWin::GuardedRun() Line 71	C++
 	kernel32.dll!00007ffef1cfccb7()	Unknown
 	ntdll.dll!00007ffef228ad6c()	Unknown

Best,

Hugo

[Attachment Removed]

Hi Tim,

I can now activate the ShowFlag.VisualizeVirtualTexture 1 with your changes in build, thanks !

Will that be a fix you’ll be applying on your end as well for a future engine version ? I’m wondering if I should submit this change to our fork or just flag this as a local change people can do to use this debug view mode in builds.

Best,

Hugo

[Attachment Removed]