Closed Koalamana9 closed 1 year ago
That sounds out of scope, especially if you don't even need voxels. There is an instancing system with a secondary mesh LOD system, but it is only for multimeshes in case you dont want to use Godot's automatic LOD, is more primitive than the features offered by visibility ranges (though those have a few issues in that case), and also it totally depends on voxel meshes. If you want this separately then feel free to fork and extract it. I haven't even a clue how I would implement streaming textures, when Godot doesn't provide it in the first place. It's something the renderer should support (at the very least the ability to load mips partially asynchronously based on some desired index, in cases the renderer can't automatically figure it out), I'm not even sure if there is a design for how this should work. This proposal has been open since 2021.
Godot's automatic LOD is kinda useless for large scenes because some LOD's should be made manually, especially merging small meshes into large chunks to reduce draw calls at distance.
Can you please explain about features offered by visibility ranges? As far as I know this can be used for simple HLOD structures but all meshes has to be preloaded into memory and stay there forever which is kinda useless, and in big scenes this will create an enormous list of nodes in a scene tree, is there is any way to unload nodes from memory using visibility ranges?
I guess no texture streaming then...
merging small meshes into large chunks to reduce draw calls at distance
FYI my LOD system doesn't do this. It does for terrain because it can't be otherwise, but not VoxelInstancer.
Can you please explain about features offered by visibility ranges?
It's explained here: https://docs.godotengine.org/en/stable/tutorials/3d/visibility_ranges.html#doc-visibility-ranges
It is a bit more flexible, but indeed it does require to have multiple nodes for each LOD, and since nothing binds them together I suspect all of them need their distance checked every frame even if only one is visible at a time (in Unity it is similar, except Unity does have a system to bind every LOD into a group known by the renderer). And then the multimesh workflow makes it fall apart because it ends up requiring to duplicate instance buffers for every multimesh LOD (since the mesh is a property of MultiMesh
, not MultimeshInstance
). Unless you use multimeshes for far, and MeshInstance for near... which is even more work to setup.
Also one feature it has is fading between LODs, which I suppose magically works with both standard materials or custom shaders (?) and I can't re-use apparently. I have to re-implement it and require users to use shaders, which is more work...
(well, as I wrote this, I just tested fade mode
and it doesn't do anything so maybe it's broken. But it's there)
all meshes has to be preloaded into memory and stay there forever which is kinda useless
Unfortunately this is also the case with VoxelInstancer, for the same reason I don't do texture streaming myself: it's a feature the engine is supposed to provide. Implementing these things in userland is suboptimal, and require more work both to develop and to use.
It's explained here: https://docs.godotengine.org/en/stable/tutorials/3d/visibility_ranges.html#doc-visibility-ranges
They added more details in latter version of the manual: https://docs.godotengine.org/en/latest/tutorials/3d/visibility_ranges.html#visibility-parent It turns out visibility ranges is tied to visibility parent parameter and every Node3D has it, so this is indeed quite versatile and parent don't even have to be an actual parent of the node, they all can be anywhere in scene tree.
This really makes me think that some more advanced structure can be made with this, as example there could be some decimated large combined mesh with a single atlas texture and upon getting close to it visibility ranges can trigger visibility parent node to be visible but instead of just turning it on it can start preloading small detailed meshes in a lazy loading manner avoiding blocking main thread, this is way better than just storing a lot of small detailed meshes (with a lot of textures) as a child at all time. As far as i'm aware 4.1 has working threaded scene processing now but I have no idea how to implement this properly to avoid any stuttering while small meshes is loading.
Well, either way in this module I develop things around voxel terrain, with mostly procedural content (so can't do fancy manual placement and handmade assets like visibility ranges are partially implying) and I also don't use nodes internally. If something is independent of voxels, it should be requested in Godot, or a different plugin.
Since Godot doesn't have a built-in HLOD system with efficient texture streaming, I was wondering if this module could be used (or modified) for just an octree HLOD system with texture streaming without any voxels? It would be incredibly useful to use it with its chunking feature manually with imported assets.