Virtual Texture/MaterialRenderProxy sequencing issue - black/missing textures in materials

We are seeing an issue where some materials are showing up with black textures, incorrect normals, etc. in standalone cooked builds (PC and console). We were able to track this down to some virtual textures not being bound properly in the materials, with a default black texture/page table being bound instead. The issue seems very similar to these two questions from 2023:

[Content removed]

[Content removed]

Running r.FlushMaterialUniforms as suggested in the first link does indeed fix the materials in our case.

I added some additional logging code, and it looks like what is happening is:

  1. Texture has its PostLoad() called.
  2. This triggers UTexture::UpdateResource(), which sets PrivateResource and then calls ENQUEUE_RENDER_COMMAND(SetTextureReference) to queue up the RT-side update.
  3. FMaterialRenderProxy::UpdateDeferredCachedUniformExpressions() is called from the Render Thread, which calls FMaterialRenderProxy::AllocateVTStack(). This calls Texture->GetResource(), but because this is running on the RT, that looks at PrivateResourceRenderThread, which is not yet set.
  4. The render command for UTexture::UpdateResource() runs on the RT, and sets PrivateResourceRenderThread, but it’s too late.

Here’s an example from the log for one texture - the log warnings are in UpdateResource and its render command, and in AllocateVTStack:

-----------------------------------------------------------------------------------------------------------

Line 13074: [2025.05.28-01.24.16:243][ 0]LogTexture: Warning: Main Thread: UpdateResource with NewResource T_ceramicTile_01_N

Line 13521: [2025.05.28-01.24.16:357][ 0]LogMaterial: Warning: Material ‘MI_ceramicTile_01’ looking for Virtual Texture ‘T_ceramicTile_01_N’, but it is not available!

Line 13524: [2025.05.28-01.24.16:357][ 0]LogMaterial: Warning: Material ‘MMI_GEN_44_room_floor_MI_ceramicTile_01’ looking for Virtual Texture ‘T_ceramicTile_01_N’, but it is not available!

Line 13527: [2025.05.28-01.24.16:357][ 0]LogMaterial: Warning: Material ‘MI__GEN_44_room02_01_tileGEN_44_room_floor_MI_ceramicTile_01’ looking for Virtual Texture ‘T_ceramicTile_01_N’, but it is not available!

Line 13644: [2025.05.28-01.24.16:377][ 0]LogTexture: Warning: Render Thread: UpdateResource with NewResource T_ceramicTile_01_N

-----------------------------------------------------------------------------------------------------------

I thought this might be related to the fact that we have a couple of SceneCaptures which run before the main view processes - perhaps that was causing the uniform expressions to be updated earlier than expected on the RT. However, disabling those did not seem to make a difference.

I am curious if this is an issue that is known and has potentially already been fixed in a newer version of the engine. We are currently running on version 5.4.2 with local modifications. It’s possible that some change we have from base 5.4 is involved here - I plan to try to reproduce this in a simpler project on the base version of the engine, but I have my suspicions that this may only manifest in the fully-populated streaming map.

Steps to Reproduce
Right now in our project this is very consistent - seems to be 100% repro on the same textures/materials every time just loading up into our main world in a standalone/cooked build.

I haven’t had a chance yet to pull assets over into a vanilla 5.4.2 build yet and see if I can get a minimal repro, but I will update this section once I do.

The issue you are describing has been an outstanding issue with the engine, which should be fixed in 5.6. Can you try integrating CL 39490954 from UE5-Main and see if this resolves the black textures?

I manually brought over all of the changes in that CL, and it does not seem to have solved the issue. I may need to bring over more than one changelist - there was at least one function DDC1_LoadAndValidateTextureData() where there were other significant changes between the 5.4 version of the code and the previous revision before CL 39490954. The new code compiles and runs, but just grabbing one function out of the previous changelist(s) probably isn’t the greatest idea.

Just checking that I integrated the correct CL: 39490954 is listed as “Update texture compiler to force rebuild textures using the standard path rather than ForceRebuild.”

Yes, that CL should be the correct one. We have had customers report to us that integrating that specific CL has worked in fixing their VT loading issue, similar to the one you described, but maybe you need a few more changes to fully resolve your own. Let me know if integrating the other changes you saw fit does not solve your issue still and I can take a closer look.

It turns out that what we were seeing was UE-209041, and bringing over CL 32054852 (3/6/2024) seems to have solved the problem for us. I rolled back bringing over CL 39490954 for now, because that does not seem to be necessary.

I am glad you could find a proper fix for the issue you were seeing. I have marked the answer so that other folks who are encountering this issue will be able to see it quickly. Thanks for following up with that. If you have any other questions, please feel free to reach out.

I don’t know why it did that weird thing with the link.