Closed TokisanGames closed 2 years ago
This is a great idea. Your approach sounds reasonable. My one concern would be self-shadowing because of a mismatch between LOD levels. I would say that, at least, at LOD0 both the shadow caster and the mesh should match. There is some room for customizability here.
Additionally, the base LOD class is generalized and not technically based on MeshInstances (which is intentional). However, it should be relatively easy to extend it and add mesh-specific options such as this one. There are some features here that could even be useful in Godot 4 despite its new LOD features.
Speaking of extending... I have been thinking of doing a refactor of this system to use at least some degree of inheritance instead of the current code duplication levels as well as some general cleanup. Have you made any modifications yet? I would suggest holding off on this until a refactor is done soon, or over the holidays (a bit short on time right now).
On the other hand, it is entirely possible to at least experiment extending the base LOD right now. But the final addition should be after a refactor.
Overall, I think this is worth implementing.
Your approach sounds reasonable. My one concern would be self-shadowing because of a mismatch between LOD levels. I would say that, at least, at LOD0 both the shadow caster and the mesh should match.
Yes, the lods should match general shape, which is why the choice for which lod to use as the shadow caster will be the user's responsibility. My tree billboards have weird shapes so aren't ideal, but lod2 is the same approximate shape as lod0.
I haven't started implementing. I have plenty other areas to work on until then, but I might want to get a trial version working in my game to squeeze more performance out of my vegetation.
I've pushed the refactors, I don't think I'll be changing much else. Should be good to add new stuff now.
Thanks. I will get on it this month.
BTW, I have some suggestions for the repository for you to consider:
Godot Multi-threaded LOD Manager
with a stub of godot-multi-lod
instead of godot-extras
. The latter makes it sound like it's someone's unfinished hobby project, rather than the solid plugin it is. Then the other modules could be relegated to an extras directory, or moved to an entirely different repo(s) depending on how many users you have for those other components.Thanks for the suggestions, that helps develop the plugin further!
I'm glad to hear you think the plugin is solid. It is sort of a hobby project that I'm slowly deprioritizing over other projects nowadays, especially since I'm slowly transitioning to Unreal. I am happy to look at smaller suggestions and/or review and merge PRs when possible, though.
I'm not sure about making it a completely separate repo, but you gave me the idea of making it a submodule, which has a similar effect. I'll take a look at doing this when I have a bit more time since it doesn't really affect functionality/not a priority.
I've added some bits of documentation for the few exposed functions.
A SConstruct file is included. Need to add a submodule to the godot-cpp repo soon.
I've added a link to the official GDNative docs.
Shadow imposters were merged in #8 . Also it appears LOD and shadow impostors are a native feature of GD4.
I'm planning on using shadow impostors and will likely patch this plugin to do so. I'd like to discuss whether you want it in your repo and how it should be implemented.
Here is what shadow impostors are: https://www.reddit.com/r/godot/comments/i2j45k/quick_tip_shadow_impostors_and_vertex_count/
Here are the performance benefits from one tree. If you switch to orthogonal shadows you get an even bigger reduction for hardly any visual difference.
To implement it, I could:
Provide a MTLOD user setting for the shadow impostor LOD: LODX. Then disable shadow casing on all LODs 0 to X-1, and leave LODX always visible and shadow only. When switching to LODX, instead of changing visibility, we just change shadow casting to normal instead of shadow only.
Instead of patching MTLOD, write a script that connects to children LOD visibility signals and adjust the settings from there. However, this means maybe 3 extra signal connections and gdscript function calls for hundreds or thousands of objects, when it could be done in C++.
What do you think?