Skip to content
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

Improve aura rendering performance #17279

Merged
merged 1 commit into from
Nov 10, 2024

Conversation

Codas
Copy link
Contributor

@Codas Codas commented Nov 10, 2024

Instead of testing each aura square against each source point of the aura, compute the full clockwise sweep polygons for the collisionType to reduce edge intersection tests in core foundry methods.
Rendering the full polygon is a little wasteful for very small aura shapes, but greatly improves performance for large auras.
In my testing on a scene with 1099 wall segments, only auras with a radius of 15ft or smaller were faster to render with the current method. I'd argue though that these aura sizes could already be rendered "fast enough".

As for performance numbers, on my system the aura drawing times improved in the following ways in the above mentioned test scene:
90ft: 195ms -> 21ms
60ft: 78ms -> 16ms
30ft: 18ms -> 12ms
15ft: 6ms -> 12ms

I know the system does not specifically cater to each and every module, but the popular "levels" modules makes modifications to the line of sight checking code that introduces additional overhead to each testCollisoin check that has no impact on the result of the aura drawing, but on the performance. With levels activated (even though the scene does not make use of it and wall-height being disabled), the time it takes to calculate the 90ft aura increases to 830ms, while staying flat at 21ms with the new implementation.

Instead of testing each aura square against each source point of the
aura, compute the full clockwise sweep polygons for the collisionType to
reduce edge intersection tests in core foundry methods.
Rendering the full polygon is wasteful for small aura shapes, but
greatly improves performance for large auras.
@In3luki
Copy link
Collaborator

In3luki commented Nov 10, 2024

Stealing this for #16984 . I never thought of creating a new clockwise sweep polygon to test inclusion. Very cool.

@Codas
Copy link
Contributor Author

Codas commented Nov 10, 2024

Stealing this for #16984 .

Thank you for your kind words :)

I'm not sure it would be a benefit in your case though. This only improves performance for the aura renderer because the source stays the same but very many collision checks are being made to different target points.
As evident in the 15ft aura case, the clockwise sweep polygon is actually slower when checking <15 or so target points because of the initial overhead in creating the polygon.

@In3luki
Copy link
Collaborator

In3luki commented Nov 10, 2024

I ran some tests with this PR on a desktop PC and a laptop in a quickly cobbled together scene with 1980 walls and one scene from Menace under Otari with 492 walls.
The measured time is the time it took to complete getAreaSquares in AuraRenderer#squares.

Results with no modules (all on Chrome 130):

PC (AMD Ryzen 5 5600X, 32 GB RAM)

Test scene (1980 walls):
90 ft. Aura
~400ms -> ~30ms
15 ft. Aura
~5ms -> ~24ms

Beginner Box Floor 2 (492 walls):
90 ft. Aura
~100ms -> ~6ms
15 ft. Aura
~1.5ms -> ~4ms

Laptop (Intel i5 8265u, 16 GB RAM)

Test scene (1980 walls):
90 ft. Aura
~700ms -> ~115ms
15 ft. Aura
~120ms -> ~90ms

Beginner Box Floor 2 (492 walls):
90 ft. Aura
~300ms -> ~35ms
15 ft. Aura
~6ms -> ~12ms

The resulting active squares are identical in my pretty convoluted scene:

Master
Master

PR
PR

Looks good to me.

@CarlosFdez
Copy link
Collaborator

CarlosFdez commented Nov 10, 2024

Thanks for doing this. A thought occured to me, and its that we might reap even more performance in the case of a token having multiple auras (a champion with marshal for example) if we pre-compute the point origin polygons using the bounds of the biggest aura on that actor, but that's probably an even more involved refactor. Correct me if I'm speaking nonsense here, this isn't my point of experience.

@stwlam
Copy link
Collaborator

stwlam commented Nov 10, 2024

Looks great. I tested against a couple gnarly AV rooms, and the results are identical there, too. Thanks for the PR!

@stwlam stwlam merged commit 82ebfba into foundryvtt:master Nov 10, 2024
1 check passed
@Codas
Copy link
Contributor Author

Codas commented Nov 10, 2024

Thanks for the extensive additional tests all of you. I'll try to include this myself next time :)

@Codas Codas deleted the faster-aura-rendering branch November 10, 2024 23:15
@theripper93
Copy link

@Codas Funnly enough, Levels used to use quadree when it used straight walls, now it does not since canvas.edges has no quadtree, there is still the relic of the rect for the quadtree in the code waiting for a core quadtree on the edges lol https://github.com/theripper93/Levels/blob/master/scripts/handlers/sightHandler.js#L415

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants