bryanedds / Nu

Repository hosting the open-source Nu Game Engine and related projects.
MIT License
1.1k stars 155 forks source link

Texture Streaming in Nu #671

Closed bryanedds closed 4 months ago

bryanedds commented 9 months ago

So, contrary to my previous conception, glTexImage2D is not likely an actionable bottleneck in texture uploading. So in order to do texture streaming, we should do the following -

1) When we discover the need for a texture in a model, instead of loading it from disk immediately, we instead create an entirely transparent gl texture2d of the correct dimensions, then add it to a concurrent list of textures to be streamed in. A fully transparent texture will work fine in both forward and deferred shading context since we check for alpha in both.

2) At the end of frame, we spawn off async ops to load the actual texture data for such textures via the vsync monad.

3) At the start of the next render frame, figure out which ops are finished and immediately and synchronously upload them to the texture where the pre-allocated transparent texture lies.

It was suggested that instead of using an empty pre-allocated texture that we instead use a fallback texture. I don't like this in our particular situation because it means that the cached constructs that are created with these texture ids have to updated, which might introduce additional system complexity. However, it might be slower on some (or all?) targets to use writable textures, perhaps. I don't know. Hence, there may be a runtime penalty for immutable texture ids either way. But if the overhead is entirely marginal, it may yet still be worth it to save ourselves from additional system complexity.

bryanedds commented 9 months ago

One question here is - without .meta files, how do we tell which assets should be loaded immediately and which assets should be streamed?

I suppose we could look to see if the asset is in a parent folder called 'Streaming' or 'Immediate'. Assets in a 'Streaming' folder should be streamed and those in 'Immediate' should be loaded when package is loaded no matter what. If in neither, then it's up to the engine.

bryanedds commented 8 months ago

Linking this related issue here - https://github.com/bryanedds/Nu/issues/708

bryanedds commented 4 months ago

Done.