-
-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
New Polyline rendering #7972
base: master
Are you sure you want to change the base?
New Polyline rendering #7972
Conversation
abb1f8c
to
4bbc4af
Compare
Badass PR !! Quesiton - is it difficult to get rid of those 2 very small triangles in ImDrawFlags_CapRound joint type ? |
Vertices in arc come from precomputed table PathArcTo use. That make their position fixed. Replacing Does those two triangles cause any issues other tham esthetic of zoomed in mesh? : ) I didn't wrote that, that fringe occupy 1px on the screen in 1:1. |
Arcs (rounded corners) was redone: Changes:
Overall this method should be faster, since it does have reduced complexity. Quick measurements show around ~15% performance gain in Release. This was was how the cookie crumbles. @sergeyn FYI |
Long Jagged (Stroke) - one of test is imgui_test_engine. Almost 20000 control points in polyline, with JoinRound and CapJoin take under 1 ms (2.3 ms in Debug). With default join (miter) and cap (butt) 0.16 ms in Release and 0.5 ms in Debug. Visually there are no noticable changes for such thin lines. |
I see, thanks for the explanation. Your reasoning makes sense and nice that
there's a way to control it if required.
…On Wed, Sep 11, 2024 at 2:55 PM Michał Cichoń ***@***.***> wrote:
Badass PR !! Quesiton - is it difficult to get rid of those 2 very small
triangles in ImDrawFlags_CapRound joint type ?
Vertices in arc come from precomputed table PathArcTo use. That make their
position fixed.
Those small triangles does fill the gap between polyline and first
triangle.
Replacing PathArcTo with _PathArcToN will generate equally spaced
triangles. It will also be alot slower, because it will call cos/sin for
every vertex on the arc.
Does those two triangles cause any issues other tham esthetic of zoomed in
mesh? : )
I didn't wrote that, that fringe occupy 1px on the screen in 1:1.
—
Reply to this email directly, view it on GitHub
<#7972 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAFDDORYJQNPPWNAAZHPBITZWA4UVAVCNFSM6AAAAABOAPJJNWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNBTGU4TGNJSHE>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Update:
Observations:
|
11bd1a2
to
27274a9
Compare
51d7012
to
a81a311
Compare
I did push dedicated implementation of Quick summary:
Overall new implementation is ~2x faster for 'square' rectangles in both Debug and Release modes. New implementation took care of few issues:
Imgui.Polyline.Add.Rect.mp4'Upstream (legacy)' is current state of the @ocornut FYI Benchmark (Stress: x5, Build: Release, Samples: 8)
Benchmark (Stress: x5, Build: Debug, Samples: 8)
|
b7bddc1
to
7287229
Compare
0e6bb15
to
14f9075
Compare
14f9075
to
d3e8da8
Compare
Out of curiosity, what is the direction of the fringe for AA. Based on the video and image. It's bidirectionnal. |
This is follow up to #2964 Render thick lines with correct thickness and beveled corners PR.
New implementation introduce more features, fixes some long standing issues and aim to be fast.
Code is feature complete, no todo's are left other than bugfixes.
Change is rather large and may look intimidating. Please read description, comment, criticque code and suggest improvements.
New Features
Fully Variable Thickness
New implementation support full range of thickness for Anti-Aliased and Aliased paths.
Support for
ImDrawListFlags_AllowVtxOffset
With 16-bit indices single command can handle up to 65536 vertices. Huge polylines are now split across multiple draw commands if necessary.
Cap Types
Support for caps on open polylines.
ImDrawFlags_CapNone
ImDrawFlags_CapButt
(new default)
ImDrawFlags_CapSquare
ImDrawFlags_CapRound
Mesh
1:1
Mesh
1:1
Important notes:
ImDrawFlags_CapButt
is new defaultImDrawFlags_CapNone
match old behavior which leave anti-aliased polyline without a capImDrawFlags_CapButt
is new default, this make all edges on checkbox anti-aliasedImDrawFlags_CapRound
is pretty yet expensive in relation to other caps typesImDrawFlags_CapRound
use adaptive rendering viaPathArcTo
Join Types
Support for more join types.
Edit: Rounded joins (and caps) are not more refined, please see #7972 (comment) below.
ImDrawFlags_JoinMiter
(default)
ImDrawFlags_JoinMiterClip
ImDrawFlags_JoinBevel
ImDrawFlags_JoinRound
Mesh
1:1
Mesh
1:1
Important notes:
ImDrawFlags_JoinMiter
collapse toImDrawFlags_JoinBevel
when miter limit is exceeded (see below)ImDrawFlags_JoinMiterClip
provide smooth transition between Miter and Bevel, it is bit more expensiveImDrawFlags_JoinBevel
is require bit more math for Anti-Aliased polylineImDrawFlags_JoinRound
is pretty yet expensive in relation to other join typesImDrawFlags_JoinRound
use adaptive rendering viaPathArcTo
Miter Limit
Miter distance count from the control point to very tip of the triangle forming a join. Sharpness of the join can be limited by using 'Miter Limit'. Miter does collapse to Bevel, MiterClip does smooth transition to Bevel.
Miter limit match SVG2 stroke-miterlimit behavior.
(borrowed from w3.org)
AddPolyline
gained new parametermiter_limit
:Default Miter Limit is set 4.0 in
ImDrawListSharedData
(internal API) and not exposed to the user.Fallback
Previous implementation of polyline is still available under different name:
New implementation does change behavior.
ImDrawListFlags_LegacyPolyline
flag is a gateway to opt-in to old rendering.New fancy tools are new and fancy, but also not mature. Setting
ImDrawListFlags_LegacyPolyline
onImDrawList
will causePathStroke()
to route all rendering to oldAddPolyline()
. This in turn for all practicall purposes will route rendering of all primitives to old code path.Reasons to set
ImDrawListFlags_LegacyPolyline
flag:AddPolylineLegacy
faster and generate less geometry.AddPolylineLegacy
does not support caps and can generate wrong geometry on acute angles.Related issues
#2183 Bug in drawing thick antialiased polylines
Status: Fixed ✅
#3366 Polyline with sharp angles causes segments to nearly disappear
Status: Fixed ✅
#4091 Optimize IM_NORMALIZE2F_OVER_ZERO
This PR does add
IM_NORMALIZE2F_OVER_ZERO_PRECISE()
that is built on top of SSE2_mm_rsqrt
intrinsics. SSE2 states that this function is an approximation of1.0f / sqrt(x)
and does have relatively large error. New macro does use newImRsqrtPrecise()
instead ofImRsqrt
.ImRsqrtPrecise()
improve precission by converging on answer by performing single step Newton-Raphson method. Exackly like in famous rsqrt found in Quake source code. This single step is enough to keep geometry consistent and to not produce cosines larger than 1.On debug (and non SSE2) builds
ImRsqrtPrecise
fallback to1.0f / sqrt(x)
, because this is faster than to perform NR step in unoptimized code. On release SSE2 builds this does use method described above.Performance
Early measurements compare old
AddPolyline()
with and without texture polylines against new implementation.I was unable to quickly test #2964, because it crashed on some tests.
Observations:
AddPolyline()
and Render thick lines with correct thickness and beveled corners #2964Test performance against Render thick lines with correct thickness and beveled corners #2964as adviced, comparison with previous PR is not necessaryPlease draw your own conclusions, or beter do your own benchmark to see change in real world.
Note:
AddPolyline()
does sometimes produce broken meshes in some tests due to lack ofImDrawListFlags_AllowVtxOffset
supportImplementation notes
General:
IM_POLYLINE_xxx
IM_POLYLINE_TRIANGLE_xxx
are overly verbose to experiment with different methods of filling index buffermov
instructions_PolylineXXX
are basically for loops with a bit of math at the beginning and 'switch' routing to selected join geometry generation codeIM_LIKELY
andIM_UNLIKELY
which are resolved to[[likely]]
and[[unlikely]]
when availableNew implementation does split problem to three cases:
_PolylineThinAntiAliased
- for thickness <= 1, technically less than AA fringe_PolylineThickAntiAliased
- for thickness > 1_PolylineAliased
- used for any thickness, does not have AA fringeAddPolyline()
:_PolylineXXX
does not need to validate inputRounted caps and joins:
_PolylineEmitArc
and_PolylineEmitArcsWithFringe
post-processing step responsible for generating adaptive arcsImAtan2
andAcos
are use for every join to feedPathArcTo
ImAtan2
is used for capsPathArcTo
_PolylineXXX
callImDrawList::_Path
, they're appended at the end