Zylann / godot_voxel

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

VoxelMeshSDF BAKE_MODE_ACCURATE_PARTITIONED does not accurately bake PrismMesh #659

Open Piratux opened 4 months ago

Piratux commented 4 months ago

Describe the bug VoxelMeshSDF'S BAKE_MODE_ACCURATE_PARTITIONED produces big gap between SDF values when baking PrismMesh. This does not happen with BAKE_MODE_ACCURATE_NAIVE.

More specifically, baking a mesh with BAKE_MODE_ACCURATE_PARTITIONED, one can notice "SDF gap" in visualisation between layers 13 and 14. Switching to BAKE_MODE_ACCURATE_NAIVE and checking visualised SDF between layers 13 and 14 show no "SDF gap".

Additional info: I've noticed this issue happen with pyramid mesh as well.

See video:

https://github.com/Zylann/godot_voxel/assets/58703216/510e6345-ab26-4116-9df6-a9bf12040adc

To Reproduce Steps to reproduce the behavior:

  1. Add VoxelModifierMesh node to scene.
  2. For VoxelModifierMesh create PrismMesh.
  3. Select bake mode BAKE_MODE_ACCURATE_PARTITIONED.
  4. Click Bake.
  5. Check SDF visualised difference between layers 13 and 14.
  6. Now repeat steps 3,4,5 but with BAKE_MODE_ACCURATE_NAIVE instead.

Expected behavior SDF produced values by BAKE_MODE_ACCURATE_PARTITIONED should be very similar to BAKE_MODE_ACCURATE_NAIVE.

Environment

MRP Test VoxelMeshSDF partitioned pyramid bake issue.zip

Zylann commented 4 months ago

That mode creates a data structure referencing triangles in chunks, and I suspect triangles are missing near the area that has the "gap" you mention.

That mode uses a compute_near_chunks function, which has a performance issue with such simple meshes. You should probably reduce Partition Subdiv to something like 8, which is much faster and also doesn't have the gap issue.

Looking more into it, I think it's simply not working properly when triangles are too big relatively to chunks: i.e if you have a mesh with only a few triangles, but subdivided so much that the AABB of triangles cover a lot of chunks, the tricks compute_near_chunks does will start producing wrong results like you're getting. It's simply not a good algorithm when used with these meshes and that config. Not sure how it would be fixed while remaining relevant. The only quick fix I have in mind is to decrease Partition Subdiv, or use another mode.

What issue is that really causing?

Piratux commented 4 months ago

It's not really causing big noticable issues (it can be noticed using grow_sphere as it relies on accurate SDF, but it's negligible). Rather just wanted to document the issue.

Zylann commented 4 months ago

Added some info in the docs in cab1b7e71c00607b0c992a6c77b760f7366492b4

Some ideas to improve the algorithm: https://github.com/Zylann/godot_voxel/blob/297286251af934ea2fb5da93e679e8b3c1ad4fb6/edition/mesh_sdf.cpp#L423-L433