Skip to main content
J
4mo ago

Optimization Question for Multiple Files in Low-Level WebGL2

As I've started adding many objects to my game, I've noticed it has been getting a bit slower and using memory usage. I initially had a different rive file for every object and character. Some were using the same riv file so I updated the code so the objects would use the same loaded rive file instance and have sperate artboard and state machine instances.

I'm wondering if it would be better to say merge all the objects into one rive file with separate artboards rather than a bunch of rive files with one artboard. What are the pros and cons?

I am only rendering and advancing rive files that are currently in the viewable in the game so one other question was is it better to delete them and re-initialize when they come back on screen, or would that end up using more resources? This could happen at any time so it seemed better to have them all ready to go at any time. The exception to this is certain cases like a cutscene that will run once per game. These I initialize right before and then delete right after.

7 replies
J
4mo ago

Just to make sure, you're only using a single canvas and loading multiple riv's into that canvas, right? I don't think having them all be in the same .riv should make a difference, as least not from a memory perspective.

Do you have a lot of large image or other assets that you're using? That can have an effect on performance.

Would you mind sharing the .rev so I can see if there are any changes I'd recommend? If you don't want to share them here, you can message use here: https://rive.atlassian.net/servicedesk/customer/portals

J
3mo ago

You are correct. I've got a single canvas that I render all the game entities onto with the low-level webGL2 canvas.

Some are using pretty large images. I know you mentioned before that multiples of 2 are recommended for images. Some of them would have to be scaled up quite a bit to make this work. Is it still recommended? I know some of these may just remain static images but right now every game object just has a riv file associated with it to keep it simple. Would it be faster to render just an image on the canvas instead of a riv file even if I don't advance the timeline or artboard at all?

Here's my folder of object rev files for the game so far.

export (2).zip
4 MB

Thank you!

3mo ago

I might have missed one, but I don't feel like any of your images were too big. The largest I could find was around 800x800px.

I did see that you're including an entire font, but only using 4 letters ("demo"). You can set it to only used "Glyphs used" and it'll take that .riv's file size down a ton.

If it doesn't animate, you shouldn't need to continue advancing the timeline or state machine so maybe that'll help. It might also be worth trying to use a single .riv with multiple artboards.

How many instances of any of these are you displaying at any given time?

J
3mo ago

Thanks! I haven't tried not advancing the timeline yet but I'll add that and see. Usually I'm just using one on at a time. The most I have is 6 instances of the demo one.

I could probably reduce rendering time a lot if I could clip the other rive files instead of drawing on top of them and include them in the single background image. Is there a way to do this in the low-level WebGL2 renderer? Here's an example of how I'm using the largest image:

It's really just layered on so it looks like the character is behind them. There may be a more efficient way to do this but I'm not sure how to clip between multiple rive files. If not, I may consider converting these to vector images if that is more efficient to render.

3mo ago

I'm just not seeing anything that should be causing performance issue, at least nothing in your Rive file. It could be something else in the code. What happens if you run the code without actually rendering the Rive elements?

J
3mo ago

Thanks for the feedback! Rendering all the objects on the busiest screen was about 10ms per frame. I was able to optimize by adding a property to the objects to indicate if they were static so I only render the artboard and I don't advance the artboard or even load a state machine. I also made a cache for riv files and artboards in the code so they will only load one if two static objects are using the same file. This cut the time about in half.

In addition to this, I was able to optimize my game code in other ways. Mainly rendering the background image as a DOM element and changing CSS from zoom and translate rather than drawing it on the canvas. This significantly sped things up on bigger backgrounds.

I think with all that I can render the max amount of objects without a significant amount of lagging.

Thanks for the help!

3mo ago

That's awesome! I'm glad you got it working smoothly!