It looks like we have some textures used by decals that get put into the unknown ref heusritic. FDecalVisibilityViewPacket determines the sorted list of decals which are then rendered by FCompositionLighting::ProcessAfterBasePass() which tags the textures in the UB as being used, however they don’t go through static instance culling, so the texture streaming system puts them into unknown ref - so they need to stream in all their mips.
Are we somehow doing something wrong to cause this?
What you describe matches the expected UE behavior.
Deferred decals are treated as unknown reference textures because they bypass static mesh culling. They projected dynamically in screen space, the engine cannot predict pixel coverage.
As a result, the streaming manager conservatively assumes all mip levels may be needed, preventing LOD popping or missing textures. Placing decal textures in the Unknown Ref heuristic is UE’s standard way of handling dynamic, screen-space projected textures.
I hope this helps clarify the case. Please let me know if you have any further questions.
Thanks for the reply. It make sense. Couldn’t UDecalComponent implement GetStreamingRenderAssetInfo() to just conservatively use the bounds of the decal projection space? I can certainly try an engine change to do that to see if it addresses our texture streaming concerns.
Edit: I see, UDecalComponent is not a UPrimitiveComponent so it has no way to do this.
I think overriding GetStreamingRenderAssetInfo to return more conservative streaming data is a reasonable approach. It allows decals to participate in view-dependent texture streaming. Just keep in mind that you may need to deal with the right balance between CPU cost and memory usage based on your case. Also, take care with edge cases, such as very large decals viewed from a distance, very small but visible decals whose bounds may cause their streaming usage to be overestimated, or potential popping issues.
I did a little more reading and because UDecalComponent is not derived from UPrimitiveComponent, the idea of overriding GetStreamingRenderAssetInfo() is not possible. After some more reading, I’m not sure I see a great way forward - FDynamicRenderAssetInstanceManager and FRenderAssetInstanceState expect to work on UPrimitiveComponent. This feels like a pretty substantial engine change to make this work for UDecalComponent. The other engine mod I considered was to make UDecalComponent a UPrimitiveComponent, however the way it’s scene proxy works isn’t compatible, which similarly seems like a substantial change.
Right, I was trying to do this without adding a new component. Thanks for the suggestion.
The implementation was fairly straight forward, however I do need to create a scene proxy because inside FDynamicRenderAssetInstanceManager::IncrementalUpdate() it requires that the component have a scene proxy. Given that I’ve configured it to have no view relevance I don’t this would cause a problem.