Zylann / godot_voxel

Voxel module for Godot Engine
MIT License
2.66k stars 250 forks source link

Setting multimesh item from scene does not set lods beyond 0 #338

Open slapin opened 2 years ago

slapin commented 2 years ago

Setting multimesh item from scene does not set lods beyond 0. Also it is not possible to change lod set from scene. It is quite severe limitation. I guess it would be trivial to check MeshInstance name suffix for "lod_0", "lod_1" etc. and set these from the same scene. Or this could be done so that

Spatial->
    BodyOrSpatial_lod0
        MeshInstance
        CollisionShape
        CollisionShape
        ...
    BodyOrSpatial_lod1
        MeshInstance
    BodyOrSpatial_lod2
        MeshInstance
...

would be used to set up lod0 and all other lods. Otherwise we can't have lods more than 1 when set from scene, which is sad.

Zylann commented 2 years ago

Yeah setting up a VoxelInstanceLibraryItem from a scene is missing that functionality. The only way is through script, or by inspector through setting the Mesh Lod N properties.

That could be achieved with the scene converter by tagging the MeshInstances somehow, with a name like you said could work. Unlike your example though, it would have to be more like this, as it's a graphics-only feature:

Spatial
    MeshInstance
    MeshInstance_Lod1
    MeshInstance_Lod2
    MeshInstance_Lod3

Note, similar to other scene conversion tools in Godot, this is a lossy process that converts to a system using multimeshes that can update fast in realtime, so not everything you can do with a scene will carry over. So LODs can only be different meshes, they cannot have different transforms, different materials, different colliders, different layers, different shadow castings etc

slapin commented 2 years ago

I guess mesh transform could be still used by either applying it to mesh vertices or applying it to multimesh transform... That would make it a bit easier to work with primitives like cube or to different set ups with meshes.

slapin commented 2 years ago

BTW do you plan to use the bundled meshoptimizer library to autolod the instancer? Not that it will produce quality results, but for messy stuff like grass and debris that would be priceless...

BTW current result with custom instance generator. Most of time no trees or grass on the roads or in buildings, but sometimes they still get through...

https://youtu.be/Y4uaQ_RMl3I

Zylann commented 2 years ago

I guess mesh transform could be still used by either applying it to mesh vertices or applying it to multimesh transform

Applying to mesh is not possible without re-importing the mesh pretty much, so that means you'd rather have to provide such offset versions basically, rather than the library doing it afterward at runtime. It also cannot be done on multimesh transform without re-updating the whole multimesh, that's a cost to pay here, and I don't really see the point if that can be in the imported meshes in the first place. Primitives don't undergo import, but I still dont get the point of offseting their lods like that. It's such a corner case that just doing it in Blender or using a script would just work without bloating the instancer.

BTW do you plan to use the bundled meshoptimizer library to autolod the instancer? Not that it will produce quality results, but for messy stuff like grass and debris that would be priceless...

Well again the issue is, VoxelInstancer is not an importer. It instantiates things and manages them at runtime, it does not import them (I know you would not want at run time, but I believe the inspector of this resource is not the right place to cram a LOD generation system) So right now you are expected to have the LOD meshes already made, it should not be happening in game or loading times. I understand the convenience, but I can't see a way to do this without bloating the system at the moment. Maybe a separate editor plugin could take a mesh, and generate multiple mesh resources that are lodded versions, which can then be used in any situation where Godot's LOD system is not working.

Also, one sad truth: the bundled MeshOptimizer cannot be used, because it is a modified version that works on terrain chunks specifically (there was no options, it is hardcoded). I had to inactivate something inside otherwise seamless junctions would not work, but that means lodding regular props would be less efficient.

Eventually (can't say when) I'll need to use this more intensively for similar goals so I'll probably see what improvements I can make.

slapin commented 2 years ago

It is not have to be at run time, it can be as that inspector button. Nice little inspector button which does lots of magic... A dream! But I will be happy enough with transform stored and used on multimesh instancing too. The reason behind this is ability to offset mesh to physics body (for example) in scene and being able to get more streamlined pipeline.

As for autolod I guess I will have to backport lod making code from godot master branch but 3.5 does not have a concept of separate index/vertex buffers out of mesh surface to implement these properly and these will have to be separate meshes to work which sounds like overkill; I wonder if it is possible to do something about that... Anyway I guess interactive/batchable mesh lod baker should not be too hard to implement...

Zylann commented 2 years ago

On master (Godot 4), fefb014637d25f1636734d657218e0603e477cd5 will allow to setup mesh LODs by using a suffix in MeshInstance node names

slapin commented 2 years ago

Would be nice to cherry-pick this into 3.x branch as Godot4's current hardware requirements make me impossible to upgrade.

Zylann commented 2 years ago

Cherry picked to godot3.x in bf0513fa753993b46203d2e11b5b005d4628a3c3