Open gotmachine opened 3 months ago
Current prototype implementation :
MODEL {}
nodeMODEL {}
node*.mu
) to find which textures are defined.GameDatabase.TextureInfo
for every texture, but as a derived OnDemandTextureInfo
class that will ultimately will be responsible for keeping track of loaded state of every texture. We assign a dummy transparent 1x1 texture to the texture reference, which will in turn be assigned to by whatever code is requesting that texture.AvailablePart
. This is done by searching through the textures referenced by the sharedMaterial
of every Renderer
present on the prefab. We keep a reference to every Material
and to every OnDemandTextureInfo
it uses.Part.Awake()
, we trigger the load of every texture and swap the reference on the cached Material
instances.This (very incomplete) prototype has shed some light on a few problems :
sharedMaterial
would be very straightforward but isn't viable. While the material is effectively shared between the prefab and just instantiated parts, any module can latter decide the part needs its own non-shared Material
instance (by simply using the Renderer.material
property). Typically, the stock ModulePartVariants
will do this on any part having the module, but we can expect this behavior in many other cases, including cases where the .material
property has been used on the prefab, in which case the instantiated copies won't share it by default (at least, I think, this need to be verified). This is also problematic if we want a non-blocking async loading mechanism, as it becomes possible for modules to make a copy of the sharedMaterial
(by calling .material
) before the textures have been swapped. Some general remarks, in no particular order :
ModulePartVariant
, they will always be loaded as usual. To include them, this require additional upfront parsing of the module config to determine which textures are used. I haven't looked in depth at the matter, but likely, this will also require some special handling to swap textures references in the material references kept by the module after part instantiation. In an ideal world, we would only load textures actually used by the current variants, but this would require additional hooking to perform on-demand loading when the variants are switched. I would put this into the stretch goals category. In any case, equivalent work would have to repeated for any other texture switcher we want to support, namely B9PS.
This is exploratory work for implementing an on-demand loading mechanism for part textures.
The general idea would be identify which textures are used in parts prior to loading them, then to skip loading them during initial game load, to finally load them selectively and asynchronously when a part is effectively instantiated in game. Textures would then be unloaded when no instantiated part is using them anymore.
The potential benefits would be :
However, the caveats are numerous :
On a side note, I'm not sure I will have the time nor motivation to get this idea to completion. But at least whatever I do will be a base for anyone wanting to pursue this project.
[*] A stretch goal could be to replace the stock cargo/inventory static thumbnails by 3D models with downscaled textures. The stock static thumbnail system generate a 256x256 texture for every part and every variant of every part, which ends up being a significant waste of VRAM. At the very least, the resolution of those thumbs should be reduced, 128x128 would be more than enough given that at 100% UI scale, the viewport for a part is 64x64.