Hi,
>> seems promising, but we found the following issue with Texture Collections: it is not working with virtual textures, which we heavily use.
I was recently told about a new feature that was added to 5.7, called Virtual Texture Collection, which aims to solve some of the issues you listed. Updates can be done per texture in the collection, instead of needing to update one single large texture. It should also be more performant than having to use UV remapping in a very large virtual texture, as it is block aligned:
Added VirtualTextureCollection's, a separate texture collection object with virtual texture backing
- Internally hosts a tile-wise atlas of the texture set. Single physical texture, all respective texture entries must share the same format and srgb mode. Alternatively, runtime format conversion is supported.
- Texture entries are naturally (mip wise) block aligned. Due to block alignment, we can avoid expensive UV re-mapping and manual sampler addressing by modifying the page table uniforms.
- Format conversion supports both virtual and regular textures, and block (re)compression should it be needed.
The feature is currently experimental and may not work in all cases. Unfortunately there is not much documentation available, but if you want to use it, please make sure to apply the patch from [this [Content removed] which fixes an issue with indexing. It also shows how to index into the texture collection with a CPD node. In the config files, you need to enable bindless resources by setting
[PCD3D_SM5]
BindlessResources=Enabled
BindlessSamplers=Enabled
in WindowsEngine.ini
and
rhi.Bindless.Resources=Enabled
As for the question of performance, it depends on the scene how much performance can be gained from optimizing draw calls by reducing the number of material instances. Will it can make a significant difference for non-Nanite geometry, Nanite draw calls work differently as Nanite decouples the rasterization of the geometry from the rendering of materials (it first draws the geometry into a vis buffer to determines which geometry is visible on screen, then uses that vis buffer to run the materials only on the visible geometry).
It’s not easy to predict the impact of such a change as Unreal Engine 5 already performs some optimizations under the hood for Nanite scenes over which you have little control. The best way to find out is to make a before/after comparison and profile both scenarios. The general recommendation is to keep material complexity as low as possible, as in pure Nanite scenes this will be bottlenecking performance more than the number of material instances. It’s better to have a few less complex materials than a single complex one (as the amount of draw calls is already optimised by Nanite).
Hopefully that helps, but let me know if you have further questions.
Sam
Sam