Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@wenjieshen
Copy link
Collaborator

@wenjieshen wenjieshen commented Oct 20, 2025

Summary

This patch partially resolves issue #3665
by improving stroke tessellation quality in the GL engine.
The updated algorithm produces smoother and more accurate stroke rendering, achieving visual results closer to the WebGPU engine.
Screenshot 2025-10-21 at 1 47 19 AM

Changes

  • Improved segment count calculation in the tessellation join process.

  • Updated the member function lineTo and close to imitate cubicTo logic, passing the Transform matrix as a parameter to round to ensure proper segment computation.

Current Status

Fixes the basic stroke quality problem described in #3665.

The odd–even rendering issue mentioned in #3668
remains and will be addressed in a future patch.

Related Issues

Partially resolves: #3665 (GL/WG: poor stroke quality)

Related: #3668 (Engines: excessive stroke width causes visual inconsistency)

@wenjieshen wenjieshen self-assigned this Oct 20, 2025
@github-actions github-actions bot added the gl OpenGL/WebGL render backend label Oct 20, 2025
@wenjieshen wenjieshen marked this pull request as ready for review October 20, 2025 17:56
@wenjieshen wenjieshen requested a review from hermet October 20, 2025 17:57
@hermet hermet added the enhancement Improve features label Oct 20, 2025
@hermet hermet requested a review from Copilot October 20, 2025 18:13
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR improves stroke tessellation quality in the GL engine by enhancing segment count calculations during the join process. The changes ensure that the transformation matrix is properly considered when computing tessellation segments, resulting in smoother and more accurate stroke rendering that more closely matches the WebGPU engine's output.

Key Changes:

  • Updated tessellation methods (lineTo, close, cap, join, round) to accept and use the transformation matrix parameter
  • Modified segment count calculation to apply the transformation matrix before computing segments
  • Ensured consistent parameter passing throughout the stroke tessellation pipeline

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
tvgGlTessellator.h Updated method signatures to include Matrix parameter for improved tessellation calculations
tvgGlTessellator.cpp Implemented Matrix parameter threading through tessellation methods and updated segment calculation logic

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@wenjieshen wenjieshen force-pushed the gl-tessellator-stroke-quality branch from cd8d408 to c8a9d03 Compare October 21, 2025 02:16
@SergeyLebedkin
Copy link
Member

@wenjieshen
I think using the entire matrix is ​​redundant for quality assessment. In this context, we're not interested in rotation and translation, only scale. There's a suggestion to initially calculate the scale
float scaling(const Matrix& m)
and then use it for tessellation.

@wenjieshen wenjieshen force-pushed the gl-tessellator-stroke-quality branch from c8a9d03 to e5e8077 Compare October 21, 2025 10:33
@github-actions github-actions bot added the renderer Core rendering label Oct 21, 2025
@wenjieshen
Copy link
Collaborator Author

wenjieshen commented Oct 21, 2025

@SergeyLebedkin
Thanks for the suggestion. I actually tried using a single scale factor, but the Bézier curves looked distorted when only the radius was scaled in 1D. That’s why I just changed it to pass a 2D scale vector instead of a matrix to the round function and added the utilities handling Bézier scaling. If this feels like too much change on utilities, I can roll it back to the previous version( the matrix solution).

Copy link
Member

@hermet hermet left a comment

Choose a reason for hiding this comment

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

@wenjieshen How about retain scale value from Stroker() constructor and access that member value from the round()? Logic will be much simple Thanks.

@wenjieshen wenjieshen force-pushed the gl-tessellator-stroke-quality branch from e5e8077 to 1033d8a Compare October 22, 2025 06:51
@wenjieshen
Copy link
Collaborator Author

wenjieshen commented Oct 22, 2025

@hermet
Thanks for the suggestion. I have changed to retain the scale as a member variable. It seems correct in several cases. I will finish the test in general later today.

@wenjieshen
Copy link
Collaborator Author

wenjieshen commented Oct 22, 2025

@SergeyLebedkin @hermet Thank you for your patience. I checked there is no regression occurring. I think this PR is ready.
image

@wenjieshen wenjieshen force-pushed the gl-tessellator-stroke-quality branch from 1033d8a to cf36ea9 Compare October 22, 2025 09:27
Copy link
Member

@hermet hermet left a comment

Choose a reason for hiding this comment

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

@wenjieshen last feedback thanks!


// Fixme: just use bezier curve to calculate step count
auto count = Bezier(prev, curr, radius()).segments();
auto count = (Bezier(prev, curr, radius()) * mScale).segments();
Copy link
Member

Choose a reason for hiding this comment

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

"multiply" a point on a Bézier curve isn't in the standard sense; Please use this way:
Bezier(prev * mScale, curr * mScale, radius() * mScale).segment()

@wenjieshen wenjieshen force-pushed the gl-tessellator-stroke-quality branch from cf36ea9 to 29a4000 Compare October 22, 2025 10:00
This patch partially addresses issue thorvg#3665 by improving stroke
tessellation quality in the GL engine. The revised algorithm produces
smoother and more accurate stroke rendering, aligning more closely with
the WebGPU engine’s output.

Implementation Details:

Enhanced tessellation logic for more precise segment count calculation.

Updated cubicTo() to pass the Transform matrix to round() for
correct segment computation.

Current Status:
Resolves the main stroke quality issue from thorvg#3665. The odd-even fill
issue described in thorvg#3668 will be addressed in a future update.

Related Issues:

Partially resolves: thorvg#3665 (GL/WG: poor stroke quality)

Related: thorvg#3668 (Engines: excessive stroke width causes inconsistency)
@wenjieshen wenjieshen force-pushed the gl-tessellator-stroke-quality branch from 8fdb98c to 900af9f Compare October 22, 2025 10:15
@wenjieshen
Copy link
Collaborator Author

I ran the Lottie examples five times on each branch (tested on macOS):

  • Main branch: 33.33 – 33.79 fps

  • This branch: 35.13 – 35.70 fps

Interestingly, this branch shows slightly higher FPS, which isn’t expected.

@SergeyLebedkin
Copy link
Member

I ran the Lottie examples five times on each branch (tested on macOS):

  • Main branch: 33.33 – 33.79 fps
  • This branch: 35.13 – 35.70 fps

Interestingly, this branch shows slightly higher FPS, which isn’t expected.

This is explained by the fact that it is most likely that the reduction in the size of the Bézier curves is more common than the scale-up, which leads to a reduction in the number of points for tessellation

@hermet hermet merged commit 3228c8f into thorvg:main Oct 22, 2025
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Improve features gl OpenGL/WebGL render backend renderer Core rendering

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gl/wg: poor stroke quality

3 participants