Skip to content

Add automatic smoothing for CSG nodes#116749

Merged
Repiteo merged 1 commit into
godotengine:masterfrom
Jesusemora:testing-changes
Mar 4, 2026
Merged

Add automatic smoothing for CSG nodes#116749
Repiteo merged 1 commit into
godotengine:masterfrom
Jesusemora:testing-changes

Conversation

@Jesusemora
Copy link
Copy Markdown
Contributor

@Jesusemora Jesusemora commented Feb 25, 2026

Closes godotengine/godot-proposals#1862

Prepares for godotengine/godot-proposals#14319 in order to implement smoothing groups, I need this and #115926 merged first, so that would be it's own PR.

Added automatic smoothing to all CSG nodes through CSGShape3D

It works on individual meshes and also on children of CSGCombiner3D.

  • Tested with CSGCombiner CSGBox, CSGCylinder, CSGTorus, CSGSphere,CSGPolygon3D and CSGMesh3D.
  • Baking to mesh preserves normals.
inspector
  • autosmooth enables automatic smoothing. This overrides any smooth faces on the mesh, meaning it works on flat faced meshes like CSGBox
smooth_cube
  • smoothing_angle: when comparing two faces of a mesh, if the angle is higher than this, the vertices are smoothed, otherwise they remain sharp.
    Setting this to a value lower than 0.1 skips the smoothing, which could lead to a performance increase.
auto_0 auto_30 auto_50 auto_80 Captura de pantalla 2026-02-25 034110 Captura de pantalla 2026-02-27 095918 Captura de pantalla 2026-02-27 100206

Comment thread modules/csg/csg_shape.cpp Outdated
Comment thread modules/csg/csg_shape.h Outdated
Comment thread modules/csg/csg_shape.h Outdated
Comment thread modules/csg/csg_shape.cpp Outdated
@fire
Copy link
Copy Markdown
Member

fire commented Feb 25, 2026

As a contributor to Godot CSG. I like the proposal.

As you know there's a per face vertex smoothing group option in https://docs.godotengine.org/en/stable/classes/class_surfacetool.html#class-surfacetool-method-set-smooth-group , we don't need to match the implementation

@Jesusemora
Copy link
Copy Markdown
Contributor Author

Jesusemora commented Feb 27, 2026

As you know there's a per face vertex smoothing group option in https://docs.godotengine.org/en/stable/classes/class_surfacetool.html#class-surfacetool-method-set-smooth-group , we don't need to match the implementation

I didn't know, and I don't see how that's relevant. CSG constructs an ArrayMesh, using a SurfaceTool would probably have a performance cost. It's also not very practical I think.

For smoothing groups I would use 0 to disable rather than -1, because it's more intuitive.

@Jesusemora Jesusemora marked this pull request as draft February 27, 2026 11:38
@Jesusemora Jesusemora marked this pull request as ready for review February 27, 2026 13:13
@Jesusemora Jesusemora marked this pull request as draft March 2, 2026 13:49
@Jesusemora Jesusemora marked this pull request as ready for review March 2, 2026 14:40
@fire
Copy link
Copy Markdown
Member

fire commented Mar 2, 2026

I mean the internals of the CSG implementation allow per vertex smooth toggles, but it's painful to expose this to the user layer.

Copy link
Copy Markdown
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally, it works as expected. Code looks good to me.

I think this is pretty good as it is from an UX perspective. I think 50.0 is a reasonable default value so that CSGCylinder3D is smoothed out of the box. We should have increased its default number of sides a while ago, but unfortunately, we missed this for 4.0.

Testing project: test_pr_116749.zip

Comment thread modules/csg/doc_classes/CSGShape3D.xml Outdated
@Repiteo
Copy link
Copy Markdown
Contributor

Repiteo commented Mar 4, 2026

Could you squash your commits? See our pull request guidelines for more information

@Jesusemora Jesusemora force-pushed the testing-changes branch 4 times, most recently from 169e1e7 to 9d77894 Compare March 4, 2026 17:35
Comment thread modules/csg/doc_classes/CSGShape3D.xml Outdated
added properties

update inspector

UX improvements

and minor optimizations

deg_to_rad

moved methods

move variables

performance and cleanup

Faster

Compare the angles/smooth of faces instead of vertices, skipping for loop.
Using a LocalVector instead of Vector, this simplifies the code while making it faster, and I don't think we need COW.

all done and working

Optimizations and cleanup

Clarifying and expanding the description of autosmooth and smoothing_angle properties.
Optimizations to skip steps in the loops:
Split loops to be able to skip vertices better and replace division with multiplication.
Suggestions for future changes.
Skip loop if smoothing_angle is lower than 0.1, as a more performant alternative to default smoothing.
Do not compare vertices that belong to the same triangle.
Remove has_smooth. Use a check at the start of the loop instead. This allows us to skip faces.
Perform normalize() at the end of the loop as we don't need the normal of the vertex afterwards, as we use the normal of the face for smoothing.  This way we skip normalizing flat faces.
If one vertex of a triangle is connected to the current vertex, the other 2 can never physically connect, so we skip them (break;). This isn't as reliable but it could add a slight performance increase.
I calculate a decrease of at least 80% of calculations in the for loops compared to the previous code.

Co-Authored-By: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
@Repiteo Repiteo modified the milestones: 4.x, 4.7 Mar 4, 2026
@Repiteo Repiteo merged commit 66a96d9 into godotengine:master Mar 4, 2026
20 checks passed
@Repiteo
Copy link
Copy Markdown
Contributor

Repiteo commented Mar 4, 2026

Thanks!

@fire
Copy link
Copy Markdown
Member

fire commented Mar 7, 2026

CSG Autosmooth behavior is affected by non-uniform scaling #117190

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use automatic angle-based smoothing for CSG faces instead of manual per-node smoothing

5 participants