atteneder / glTFast

Efficient glTF 3D import / export package for Unity
Other
1.24k stars 251 forks source link

Pooling of textures and materials #447

Open andypoly opened 2 years ago

andypoly commented 2 years ago

Is your feature request related to a problem? Please describe.

Runtime importing: Many models in our case have shared materials (at least in name and appearance) and textures may be shared also. Currently glTFast seems focused on individual scenes and models, with no consideration for shared resources like this. GltfImport.Dispose() will dispose of all materials and textures so, as-built, the code seems not able to use shared resources for those. You can simply avoid disposing the imported meshes in some cases, but not if that memory is needed.

Describe the solution you'd like Support for (or an implementation of) pooled materials and textures that are shared between models & do not get disposed of by GltfImport.Dispose() A minimal option would be a Dispose call with options for which resources should not be Disposed.

Describe alternatives you've considered Modifying GltfImport.Dispose! and building custom material generator and download providers that pool resources

Additional context

atteneder commented 2 years ago

Hi @andypoly,

Thanks for the suggestion.

I can imagine that a texture (or even a buffer), that is referenced by multiple glTFs (e.g. via identical URI) can be downloaded and decoded just once.

One solution to that could be custom IDownloadProvider implementation that also serves as Texture cache.

How would you go about materials in the same matter? I don't see a method of either cross-referencing another glTF's material or matching/coupling them, other than comparing every single attribute and figure if they are identical.

andypoly commented 2 years ago

Hi so I have implemented this, but in a specific way for our needs - I have a custom MaterialGenerator, which reads the material names only (!!) and then assigns a material from a library based on that name. Textures could be read in and pooled but not done yet. But I could not call the current Dispose as that would delete shared materials (I do not want to duplicate any - though depending on the graphics pipeline that may not be a problem...). Thus I had to modify the code to optionally not dispose materials.

So the flexibility of the API lets me do so much, but there are limits - I suppose GltfImport could be inheritable...?!

I guess just textures would be the main case for pooling for more general use.

atteneder commented 2 years ago

Yes, you could inherit from GltfImport, but it's far from cleanly structured to allow targeted adjustments. I could refactor it to those needs though if you give me suggestions.

Thinking more about it, IDownloadProvider should probably not implement the caching, as it won't work for non-texture downloads (KTX or some others as well).

I'll keep that idea around, but no immediate action on my side for now.

Connor-Kerwin commented 9 months ago

@atteneder Are there any updates on this feature request? Something like an ITexureCache or IMeshCache interface passed into the GltfImport object would be really useful.

atteneder commented 3 months ago

@Connor-Kerwin No work has been done, but feel free to propose something in a draft pull request.