How to apply full-screen SKEffectNode for post-processing in SpriteKit
Asked Answered
B

1

6

I'm trying out SpriteKit with the following setup:

  1. An SKScene with two child nodes used merely for grouping other nodes: foreground and background.
  2. background is really empty as of now, but would eventually hold some type of background sprite / layers.
  3. foreground is a SKEffectNode and whenever the user taps on the screen, a new intance of a SKnode subclass which represents a game element is added as child to it.
  4. This SKNode subclass basically creates 3 SKShapeNodes and two labels: an outter circumference, an inner circumference, 2 labels and an inner quarter circumference. The inner quarter circumference has an SKAction that makes it rotate forever about its origin / center.

Now here's the issue, as long as foreground doesn't have any CIFilter or has shouldEnableEffects = NO, everything is fine. That is, I can tap on the screen and my game elements are instantiated and added to the main scene. But the minute I try adding a CIGaussianBlur or CIBloom to the foreground, I notice two things:

  1. The framerate drops to about 2fps. Mind you, this happens even with as little as 6 nodes alive in the scene.
  2. The effect seems to be constantly cropping its contents or adjusting it's frame. That is, if I have one node, the "full screen" effect seems to try and constantly crop or adjust its bounds to the minimum area required to hold all nodes. This is for one node:

    enter image description here

And this is for 2 nodes:

enter image description here

In OpenGL ES 2, one would do a post blur / bloom by basically rendering the whole framebuffer (all objects) to texture, then doing at least one more pass to blur,etc on that texture and then either present that in the framebuffer attached to the display or compose that with the original render back to the framebuffer. I'd expect SKEffectNode to work in a similar way. However the cropping and the poor performance makes me think I might be using the effect node the wrong way. Any thoughts?

Blob answered 21/9, 2013 at 20:48 Comment(0)
O
3

It seems to be a bug with the SKEffectNode trying to apply a filter on children SKShapeNodes as far as I can tell. I played around with this and achieved your results, but when I switched out the SKShapeNodes for SKSpriteNodes (using a simple png of a circle) the cropping no longer appears. It's a bug in that SKEffectNode doesn't handle the stroke of the SKShapeNode very well. If you take off the stroke (lineWidth = 0) and give it a fill color, you'll see that there is no cropping.

As for the frame rate, SKShapeNodes perform poorly. Doing the switch to SKSpriteNodes I mentioned earlier boosted my fps from 40 to 50 when I had 35 nodes on the screen (iPhone 5) with the filter applied.

Officinal answered 22/9, 2013 at 1:10 Comment(3)
Now that I think about it, there might be a workaround: the SKView is backed by a CAEAGLLayer and even has a -textureFromNode property which returns a SKTexture. If I set up my own GL shader for blurring/blooming I could grab each frame (via the property or perhaps even by tapping into the layer itself with my own OpenGL context), post-process it and present it back either in the SKView's layer or a new CAEAGLLayer.Blob
Can you comment on if this work around worked? I'm trying to figure out if you can do your own post processing effects using Sprite Kit?Jae
would love to see some code for this... having trouble finding how anyone applies SKEffectNode for these post effectsCounterpressure

© 2022 - 2024 — McMap. All rights reserved.