godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Add a CSG deformation node for more advanced in-editor 3d modeling #8149

Open wareya opened 1 year ago

wareya commented 1 year ago

Describe the project you are working on

Various small 3d games.

Describe the problem or limitation you are having in your project

When I want to make level geometry that's more complex than rectangles and maybe some cylinders or prisms, I have to open up blender and go through the process of setting up materials, exporting to glb, making sure the glb is being imported properly in Godot, going back and forth a few times etc. This is the case even when I'm trying to make something fairly simple like a rock, which is basically just a distorted low-poly sphere.

Godot's CSG geometry system is an incredible strength, but it doesn't lend itself well to organic or natural geometry. If Godot had more powerful tools, even if they were fairly limited in scope, it would be much easier to make game prototypes entirely within Godot.

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

I propose a CSG node that, rather than adding new geometry or acting as a way to better control the operations of its child nodes, deforms the mesh created by combining its child nodes. This would allow for organic and natural modelling tasks to be done (even if only to a low degree of fidelity) entirely within Godot.

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

There are three reasonable strategies for deforming CSG meshes:

1) Modify the verts directly, making a 1:1 mapping from source vertex to deformed vertex, like a shape key. This has the problem of "if you modify any of the child CSG geometry all of your work disappears". Also, repairing vertex normals/tangents after doing this is slower and more involved than the other strategies. 2) Record all the deform operations and apply them from scratch whenever the underlying mesh changes. This has the problem of infinite memory consumption bloat, and the more operations you've done to an object, the slower each update gets. 3) Morph a lattice of deform offsets. This is the method I recommend; I've implemented it and it works well. The downside is that it's less intuitive and requires you to set up the lattice size and resolution before you start working.

After deciding on a strategy, the rest is just intercepting child geometry once it's done combining and applying the deformation to it. I implement this in a proof of concept here (it's pure gdscript; it's a lot slower than it would be if it was C++): https://github.com/wareya/CSGDeformTest

This proof of concept isn't fully usable; there's no way to easily deform the CSG collision from gdscript if collision is enabled. If this proposal is widely supported, I can port the proof of concept to C++ and open a PR.

Godot_v4 1 1-stable_win64_2023-10-16_09-09-49

Video demo: https://www.youtube.com/watch?v=rx_-kUpJ0CQ

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

No quick workaround.

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

This could be an addon if more of CSG internals were exposed to addon APIs. However, the implementation is relatively simple, so having it in core wouldn't be excessive bloat. The proof of concept is around 700 lines of gdscript total between to script files; the C++ would be more verbose, but still.

I think this would be very beneficial to most 3d game projects. I imagine that more projects would use it than the GridMap node. It would be unfortunate if the first thing every 3d godot game dev was told was to download some specific addon to make organic modelling easier.

fire commented 6 months ago

I was able to improve Godot CSG quality, so dependent proposals are unblocked.

https://github.com/godotengine/godot/pull/91748