-
-
Notifications
You must be signed in to change notification settings - Fork 35.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ExtrudeGeometry: Fix triangulation #30698
Conversation
19cad39
to
5753c10
Compare
📦 Bundle sizeFull ESM build, minified and gzipped.
🌳 Bundle size after tree-shakingMinimal build including a renderer, camera, empty scene, and dependencies.
|
5753c10
to
116494a
Compare
Thanks for the contribution! Nice to see there may be a good CDT algorithm available in Javascript. A few questions:
Can you provide a before and after example demonstrating the issues that this fixes? And why? From the screenshot changes it looks like CDT will provide a significantly more dense triangulation (or perhaps the triangles are just concentrated in different places). Do you have a rough idea of how much this increases the complexity of the resulting geometry?
If I'm reading this right it looks like the cdt2d package isn't being treeshaken - likely because the cdt2d file can't be determined to be side-effect-free. I'm wondering if there's a way to auto-convert the file to a more well-formed es6 module style file to clean this up using something like Rollup. Also for anyone else the repo for cdt2d is available here. |
Ah, that makes sense that the FX in that example uses the mesh triangles. That explains the example failure, though not why it doesn't work on remote.
I haven't compared it between the two methods in detail. The resultant triangulation is more accurate to the original contour, whereas Earcut literally cuts corners, so I'd expect there to be a higher triangle count. I can look into it for solid numbers.
Sure, I'll put something together. The inciting incident is #20317, which shows that certain contours will produce large noticeable triangulation artifacts, such as triangles crossing what should be empty space or truncating corners. From my investigation, this seemed to be independent of bevelOffset, though certain values for the offset would trigger such a result due to the changes made to the contour.
I agree. I've got a fork open to generate the bundle, it should be simple to experiment with other bundling options. I'm not sure if there's a good way to test the results short of pushing to the PR and letting it run its CI. I'll fiddle. |
There may be differences in blending, antialiasing, etc between your local and host machines. We can deal with this once the rest of the implementation and questions are settled.
This is not an intrinsic quality of the earcut algorithm. A completely robust version of earcut should not have the artifacts shown and should follow the contour exactly but it can be difficult track down all the corner cases. There are number of filed issues in the original earcut repo that three.js' is based on (see mapbox/earcut#174, mapbox/earcut#163, mapbox/earcut#162, and others). I'm not completely convinced that using something like this cdt library won't just move these errors and corner cases somewhere else but if it's working in a number of examples and fixing known issues it should be considered. We should still understand the practical impact on triangulation complexity and performance for projects already using the ExtrudeGeometry class.
Perhaps @Mugen87 or @marcofugaro knows how file size and treeshaking impact can be tested locally. We should also hear Mugen's or @mrdoob's thoughts on including a bundled library in core before spending too much time on the treeshaking bit - external library inclusion is typically relegated to the "examples" folder. Though the earcut algorithm was ported from mapbox to be included in the core project. |
In general, I do not vote to have two triangulation libs in the core. We should either use Earcut or this one. TBH, I prefer a non-bundled code for clarity reasons. The current Besides, would upgrading I do not vote to go for "best triangulation quality" if the required lib adds a lot of code to the engine. We should have a good compromise between size, speed and quality and I'm not convinced yet that |
I've done some benchmarking and unfortunately the CDT version of ExtrudeGeometry seems to more than 4x slower than the earcut version, probably from some of the other features CDT affords over earcut. The triangle count is about the same, though. While I prefer the triangulation and robust of the CDT implementation the performance loss is not ideal.
We should not be modifying library code, though - there's no reason to do that. Any fixes should be made upstream. The fact that we've copied Mapbox's earcut code and modified function names makes it more difficult to maintain. There have been updates to the earcut project (unclear whether they'll fix the issue in question here) but if the file were imported as intended then we could just update a version and benefit from any fixes. |
@mlasala45 It should be possible to monkey-patch
three.js has no dependencies and at the time earcut was integrated there was no willingness to change that. The policy at that time was three.js should be self-contained as much as possible. |
Personally, as a 3D app developer, I'd seriously value the option to choose higher quality at the expense of performance. Rather than replacing the current version, maybe there's a way to make that option available without compromising engine size; eg. an optional module that has the three.js rubberstamp.
Good point. Definitely doable, though ideally there'd be an officially supported option.
If #30737 goes through, I'll see if the newer earcut version fixes the triangulation problem. |
Also reverts test screenshot changes
That sounds good! In this case, I think we can close the PR and continue the usage of earcut. #30737 improved the integration so it's easier for us to update the library in the future. If you encounter triangulation issues, it's indeed better to follow the suggestions in #30698 (comment) and report the issue at the earcut repository. When fixed there, we can simply upgrade |
@Mugen87 I think you misunderstand. The modified version of this PR still fixes triangulation issues present in the library. It's just that those issues were caused by uncleaned input geometry data, not by a faulty earcut implementation. The PR as it stands improves readability and documentation of the affected files, and adds data cleaning (specifically point welding) to the ExtrudeGeometry process, which fixes the issue as shown above. |
I personally would prefer to see the fix made in a separate PR from so many cleanup changes so it's more clear what the meaningful changes are. |
@gkjohnson New PR at #30750 |
Sorry, to be clear I would like to see the "welding fixes" only without any variable renaming and extraneous comment changes. Please only include the changes necessary to fix the triangulation.
These extra changes make the PR more difficult to follow and understand. |
Gotcha. Would you prefer I remove the new pr, to keep it in one thread?
…On Mon, 17 Mar 2025, 10:45 pm Garrett Johnson, ***@***.***> wrote:
@gkjohnson <https://github.com/gkjohnson> New PR at #30750
<#30750>
Sorry, to be clear I would like to see the "welding fixes" *only* without
any variable renaming and extraneous comment changes. Please only include
the changes necessary to fix the triangulation.
Also improved variable names and commenting in the affected files.
These extra changes make the PR more difficult to follow and understand.
—
Reply to this email directly, view it on GitHub
<#30698 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A4IPUR7SUJGGP75YQLQUL3L2U6CDHAVCNFSM6AAAAABYUST6XSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDOMZRGQ2DSOJYGA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
[image: gkjohnson]*gkjohnson* left a comment (mrdoob/three.js#30698)
<#30698 (comment)>
@gkjohnson <https://github.com/gkjohnson> New PR at #30750
<#30750>
Sorry, to be clear I would like to see the "welding fixes" *only* without
any variable renaming and extraneous comment changes. Please only include
the changes necessary to fix the triangulation.
Also improved variable names and commenting in the affected files.
These extra changes make the PR more difficult to follow and understand.
—
Reply to this email directly, view it on GitHub
<#30698 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A4IPUR7SUJGGP75YQLQUL3L2U6CDHAVCNFSM6AAAAABYUST6XSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDOMZRGQ2DSOJYGA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
I don't have a strong preference on whether it's a new PR or in this one. |
Closing in favor of #30750. |
Related issue: #20317
Description
Fixes triangulation errors for various shapes that were caused by the Earcut algorithm. Changes ExtrudeGeometry to use cdt2d (Constrained Delaunay Triangulation) instead, which is added as a bundled file. Geometry data is now cleaned prior to triangulation, welding adjacent vertices that are within a certain distance threshold (currently 0.0002; this should probably be a config option).
Triangulation is now consistently accurate. It can still experience errors for geometries with holes, but only if the hole is wound backwards, which is easily fixable.
Also improved documentation/commenting for ExtrudeGeometry and ShapeUtil.
The E2E test
webgl_custom_attributes_lines-diff
runs correctly on my local machine but not on remote; I suspect its timing or its colors are not sufficiently deterministic.