简体   繁体   中英

SpriteKit - How to improve performance?

I'm making a simple performance test using SpriteKit where I create thousands of SKSpriteNodes, 50 by 50 pixels in size, no texture and rotate them using SKAction.rotate(byAngle:) and remove them on collision with an other SKSpriteNode that follow the position of the mouse.

For collision and contact I don't use SKPhysicsBody because it is very heavy on performance, instead inside the update method I use a For loop to compare the position of all sprite nodes agains the one follow the mouse.

I'm getting decent performance, I can maintain 60 FPS while having 17k sprite nodes on the screen. However, my problem is that with other frameworks using OpenGL and Vulkan for rendering I'm getting much better results in a similar scenario where I can maintain 60 FPS with 30k sprites on the screen. Since Apple embrace Metal and SpriteKit meant to be really fast, I was expecting SpriteKit to be the fastest in this simple experiment and wondering if it something I did wrong.

I did look in to how to optimise performance in SpriteKit and the only relevant information I've found was to set ignoreSiblingOrder property of skView to true to batch render sprites with the same zPosition. It did help and the FPS went from 40 to 60 with 17k sprites on the screen. This is where I am right now.

I could not find any other information that I could use. I suspect I could improve the way I compare position of sprites inside the update method but I'm not sure what options are there if any. This is how the code looks like:

override func update(_ currentTime: TimeInterval) {
        
        for i in greens{
            if i.position.x - 25 < mouseSprite.position.x + 25 && i.position.x + 25 > mouseSprite.position.x - 25{
                if i.position.y - 25 < mouseSprite.position.y + 25 && i.position.y + 25 > mouseSprite.position.y - 25 {
                    i.removeFromParent()
                }
            }
        }
        
    }

If I disable this code and I don't remove any sprites then I get 60 FPS with 30k sprite nodes on the screen while in other frameworks I can render 50k sprites on the screen at 60 FPS if I do the same. SpriteKit is the slowest and I was not expecting this considering many Apple developers seems to recommend SpriteKit for better performance and wondering if am I doing something wrong?

Is there any techniques I could try to further improve performance with SpriteKit and get similar results to the other frameworks that uses OpenGL and Vulkan for rendering?

Thank you.

Is there any techniques I could try to further improve performance with SpriteKit

I'm going to focus on that portion, because you'll never achieve the same performance with a heavy, general-purpose library as you would by writing by hand exactly what you need (as you would working with bare-bones Vulkan code for example).

Optimizing SpriteKit itself is also out of reach, what is, is.

What you can do is focus on your own code. Specifically looking at your update function you're iterating over every single object every single frame in the hopes that they're under your mouse, but the mouse position can only be in one place on the screen at a time. So if you partition your data in screen quadrants you're able to only test a tiny subset of all of those.

You can either do it in an uniform grid (like 10x10 or something, depending on your window shape), or write a full blown octree which partitions groups into more buckets the more they're clustered.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM