-
Notifications
You must be signed in to change notification settings - Fork 26
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
Set effect render visibility based on token vision #290
Conversation
50332a5
to
99fdb68
Compare
What are the optimizations that masking prevents? |
That's a bit more complicated. The answer is "draw call batching" but that alone is probably not helpful. Essentially, when drawing something with WebGL, many operations have to be performed. Shader set that is to be executed, geometry and textures registered etc but that is akin to just setting some flags in an object in JavaScript. Good news is that very often a bunch of stuff can happen in one draw call even. Moden GPUs Fire example can upload and reference up to 16 textures in one draw call, which in the case of sequencer means that potentially up to 16 effects could be rendered at once. In case of sprite sheats (which are one texture) this even increases to 16 unique effects, meaning 50 times the same token animation for example could still be just one texture in one draw call. the problem is that in order to mask one effect, this effect has to be rendered in its own to then be masked or cut into shape. This is one draw call to draw the effect to a separate texture and one draw call to mask the effect. Which means that instead of one draw call for 16 effects (the one performance heavy operation) with masking 16 effects would introduce 32 draw calls. One each for rendering the effect, one for masking. In absolute performance numbers this means that one animation im working on and something like aura effects could tank my performance to unplayable frame rates whereas without masking there is hardly any performance impact at all. |
Interesting - does this draw call consolidation require a new PR then? I'm open to adding an option to have some levels of detail in this regard, so that we can optimize it a bit. Is there any way we could consolidate draw calls of non-masked effects separately from masked effects? |
No, nothing has to be changed. Batching is done automatically. Currently each effect also has additional filters applied (which work the same as masks with regards to breaking batching and how they are applied in PIXI), but this will be taken care of in my other PR #275. Though that one has to be updated with this code and to re-enable masking if it is enabled. With regards to batching: All effects that are rendered in sequence that have neither masks nor filters applied should be batched automatically up to a certain limit (8 or most often 16 textures for modern GPUs). For example:
could be rendered in batches of: All in all this could be rendered in 5 draw calls. I really think just introducing a setting, something like "enable effect vision masking" that is enabled by default or something like this would be best. That way people with slower hardware could just disable masking for a large performance increase and everyone else just gets the best visuals. This PR really does one thing, not rendering effects that are occluded by walls etc from the vision of tokens.
|
I'll close this (for now) in favor of the vision mask batching PR. This might still be a nice performance improvement in certain cases, but it also has certain problematic edge cases I want to examine in more detail |
Currently, masking is used exclusively to hide effects that are occluded from token vision by walls etc.
This means currently every effect on the game canvas is still rendered and then cut from the canvas, even though it might not be visible at all.
This PR calculates visibility of effects based on the 4 corners and the center (+tolerance) of the effects bounding box with the vision polygon and sets the
PIXI.Container
s visibility tofalse
in case it is not visible.With this PR I also want to open a discussion about effect visibility masking:
Masking of effects completely removes every possibility that the drawing of effects can be batched which introduces a significant performance bottleneck.
Since now effects that are not inside the players vision (based on the effects boundin box) are not shown at all, I think it can make sense to move the masking operation of effects behind a performance setting.
Maybe by default only apply masking if foundry performance is set to high or above with a separate override in the Sequencer settings?