godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.12k stars 69 forks source link

Improve automatic mesh LOD generation to better preserve silhouettes at high simplification levels #3861

Open mrjustaguy opened 2 years ago

mrjustaguy commented 2 years ago

Describe the project you are working on

Game

Describe the problem or limitation you are having in your project

See Images Below

GODOT Full Mesh G0 50% Polycount G1 25% Polycount G2 10% Polycount (LOWEST) G3

BLENDER Full Mesh B0 50% Polycount B1 25% Polycount B2 10% Polycount B3 1% Polycount (Could go a little Lower still) B4

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Godot's auto LOD has problems. 1) No Symmetry support 2) LODs are very Aggressive in terms of Quality degradation, while not being that great at reducing Polycounts. 3) Lowest LODs still have plenty of Polygons

This is all in Comparison to Blender's Decimate Modifier that was used for the Images above in the Collapse Mode. Implementing Something like That would Significantly Improve Quality, and Would also Improve Performance when the Meshes are farther away, significantly when there are many Auto LOD Meshes far away.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Instead of using the current Auto LOD generation methods, Try doing something similar to Blender's Decimate in Collapse Mode, as that gets way better results, while also being very easy to control how many polygons are being cut as it just cuts a percentage of triangles you specify, and also supports symmetry that can be somewhat important in keeping quality consistent for quite a few meshes as it's quite a common thing.

If this enhancement will not be used often, can it be worked around with a few lines of script?

No.

Is there a reason why this should be core and not an add-on in the asset library?

Auto LOD is Core.

Calinou commented 2 years ago

No Symmetry support

In a game with complex meshes, perfect symmetry in meshes is uncommon. A realistic character will never use a symmetric mesh, simply because humans (and their clothing) are not symmetric in the first place :slightly_smiling_face:

Instead of using the current Auto LOD generation methods, Try doing something similar to Blender's Decimate in Collapse Mode

Blender's Decimate modifier doesn't have a great reputation among 3D modellers (not to mention its code is GPL-licensed, which means we can't copy it). Its proprietary competitors like Simplygon are much more renowned in comparison.

Remember that Godot's automatic LOD is only meant to kick in when far away from the mesh. It doesn't matter if the mesh looks all garbled when up close if it looks fine when it occupies 10 pixels on the screen.

mrjustaguy commented 2 years ago

I know it's GPL licensed and cannot be used in here, so it's more of a suggestion of what sort of thing to aim for.. Also the Pictures were taken at the Same distance to show the gigantic difference in quality, which would translate into better quality at a distance too, albeit very slight, but also a Massive improvement in performance due to a Colossal reduction in triangles rendered at each of the LODs.

The 1% poly mesh is using only ~300 triangles while the lowest Godot's Auto LOD renders is ~3000 triangles which matters a Ton when you've got a thousand or so instances visible on screen.. Not to mention the fact that the 25% polycount decimated LOD can be used where the current 50% polycount Auto Generated Godot LOD can be used, which translates into ~7500 triangles less can be utilized for the same distance, and you can more aggressive with reducing triangles closer by without massive quality loss, which can yield massive performance improvements.

Anyhow as I know this is a bit of a tall order, I've opened https://github.com/godotengine/godot-proposals/issues/3860 to provide an alternative to Auto Generated LODs without creating dozens of Mesh Instances to do HLOD or Creating elaborate scripts to switch LODs on Meshes.

fire commented 2 years ago

Can you post tests based on pixel size (edge length) on screen?

If you post the sample, I want to also see if we can tune the normal angle for mesh LODs.

Edited:

The way the LOD tool works is it requires the mesh triangles are evenly distributed and if the mesh is not the algorithm cannot pick vertex indices to reduce the lod.

I was looking into intrinsic triangulation for better Godot Engine LODs.

http://geometry-central.net/surface/intrinsic_triangulations/basics/

I am also looking into quad retopo for external use.

https://github.com/nicopietroni/quadwild

mrjustaguy commented 2 years ago

Here's the Sample's Blend file used. Sample.zip

I've tried some tweaking of the mesh LOD settings and I didn't get very far with the results. The Mesh Triangles are very much NOT evenly distributed in the sample, the Face and Hair have much denser topology compared to the suit, and also another thing that's possibly throwing off the LOD are the Tongue and Teeth inside..

fire commented 2 years ago

I'll write about this more.

  1. open in blender
  2. use 3d tool
  3. make all manifold
  4. some are left
  5. separate by loose parts
  6. Delete hair strands that were non manifold
  7. 0 manifolds
  8. dissolve degenerate
  9. remove doubles
  10. triangulate
  11. check again
  12. git clone --recurse-submodules https://github.com/fire/navigating-intrinsic-triangulations-demo -b save-obj
  13. install scoop, ninja, mingw-llvm, ...
  14. code patch..
  15. ???
  16. Go to godot and set normal divide to 1 degree
  17. bin\int_tri.exe Female1-Female.obj
  18. Play with Deluany refine and export vertex positions.

Set to lod bias 8.

image

image

image

image

Nothing conclusive though.

int_tri.zip Female1 GLB.zip Female1.zip

fire commented 1 year ago

As part of https://github.com/godotengine/godot/pull/73734, I was looking into this with mesh lod set to 8 and 8 bone influences. There appears to be corruption. This appears to be a bug in godot engine.

image

fire commented 1 year ago

Testing as part of https://github.com/godotengine/godot/pull/73734 pr.

LOD biased to 1

https://user-images.githubusercontent.com/32321/220754004-6c152921-d062-490c-bcef-a1dee1619094.mp4

LOD biased to 8

https://user-images.githubusercontent.com/32321/220754015-0b04f315-2e1a-435c-93e9-d4a21bddcba1.mp4

Calinou commented 6 months ago

@mrjustaguy Can you test the master branch to see if things have improved following the merge of https://github.com/godotengine/godot/pull/84384? The changes from that meshoptimizer update may be enough to address this proposal.

mrjustaguy commented 6 months ago

It is significantly better, at 25% polycount in Godot the results are similar to the 10% polycount in blender, however below that it starts falling apart just the same, and there seems to still be a limit on how low it'll decimate it (so gets stuck at just under 10% polycount) and still looks at that level basically the same.