Reducing 3D renderer loading time

Captain's Log: Stardate 78261.3

Okay so as mentioned in prior updates, the skybox and 3D assets for Anukari are now things that the user can configure. This is great, but it highlighted some existing problems.

For example, while auditioning which skyboxes I want to include in the factory set, I discovered that while it looks really nice to load the skybox in 2K resolution, but that requires reading up to 256 MB from disk, which is really slow. The main problem this caused was very slow loading time for Anukari, and when you select a new 2K skybox in the GUI, the interface would hang for a while while it loaded.

Those problems are somewhat tolerable, since changing skyboxes isn't something you do constantly. But when you run Anukari as a VST plugin, it is very common to open and close the plugin GUI window constantly. And the latency penalty for loading the 2K skybox was being paid every time the GUI window was re-opened. And really it's not just the 2K skybox penalty that I care about; it's just the most noticeable thing. But even creating a Filament renderer from scratch takes ~150 ms which is noticeable. Clearly this is not cool. What I did to eliminate all this latency is twofold.

Asset Async Loading

To prevent GUI jank when the user selects a new skybox (or 3D assets or whatever), I modified the asset loading system to be able to pre-load assets in multiple background threads. When the user chooses a new skybox, the data is loaded from the disk in the background and the rendering thread periodically checks to see if the data is ready. Once it's ready, it creates the new skybox from the data (which is very fast). This not only gets the slow disk loading out of the GUI thread, but also the renderer thread. So now the GUI is completely smooth the whole time, and there's just a small delay before the "change skybox" action becomes visible. This also means that at startup everything loads and becomes usable instantly, while the 3D stuff loads and seamlessly pops in later without blocking.

Renderer Caching

So in the VST world, the host application (DAW) can do kind of whatever it wants with the native window that displays your VST plugin's GUI. The DAW is responsible for creating and destroying the main native window. So the VST plugin needs to be able to create/destroy its GUI each time the DAW asks it to do so.

Normally this is so fast that it's not noticeable. But because Anukari's 3D renderer needs to load potentially expensive assets off disk, it can be very noticeable and annoying. And even without expensive assets, just the basics of initializing the renderer/shaders/etc takes a noticeable amount of time.

What I ended up doing is modifying Anukari's renderer so that it can be detached from a native window and re-attached to a new one. So behind the scenes, when the DAW closes the VST GUI window, Anukari detaches the renderer from the old window, caches the renderer, and destroys the GUI. Then when the DAW opens a new window, Anukari brings up the GUI and then attaches the renderer to the new native window. The result is when the user re-opens the Anukari's VST GUI after closing it, it is completely instantaneous. It feels really good.

Now, there's a tricky bit here, which is that technically the VST standard allows multiple GUI windows to be open at the same time. I haven't used a DAW that does this but I've heard they're out there. For now, Anukari only caches a single renderer instance, and it cannot be shared among multiple windows. So if a second editor is simultaneously opened, it will have to load the 3D assets. Not great, but it will all work correctly aside from the latency. If anyone actually uses Anukari in this way, maybe I'll consider improving it, but it seems like a tiny edge case.


© 2024 Anukari LLC, All Rights Reserved
Contact Us|Legal