Screen shader in a game with a moving camera

In my game, I have an SKScene with a camera node. Camera node is moving vertically far beyond the initial frame bound (think Space Shooters game where your ship is flying up). Camera node Y coordinate is changing constantly.


I need to apply a custom shader to the currently visible area of the screen – essentially, I want the shader to receive what user sees on the screen as a texture. Is it possible to achieve such effect with the described setup?

The whole SKScene is a SKEffectNode, so you can direcly apply your shader on the scene if that's what you need. Performance may be an issue depending on your shader/scene.


See here : https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKEffectNode_Ref/index.html#//apple_ref/occ/cl/SKEffectNode

So, I did that but shader only applied to a static area of the scene – as the camera moved that area went out of sight.

I ended up adding an SKEffectNode to my scene and making everything a child of that and it worked until I ran into the https://forums.developer.apple.com/message/124440#124440.

Bah ! I really hoped they had considered the SKCamera thing for SKScene, that's pretty disapointing. I strongly suggest you file a bug on radar. Is the area 2K x 2K or just the screen size ? In any case, I think the correct way it should work is that they reframe the SKScene's effect buffer to camera.


I replied to you on the other thread but that won't help your specific case I guess.


Since you can't really move SKEffectNodes anyway, hmm, I guess they just center the buffers around default screen position every time and be done with it. Hard to think of a workaround. If it's just a static effect (say a shader for your menu when you pause game) you can screenshot and apply either a CIFilter on top, or just make that a node on top and shader it, but for realtime not sure it will help.


I use that to get a full scene screenshot :

cacheTexture = [[self view] textureFromNode:[self scene]];

Yeah... The shader is realtime.


So, my scene is being built in code in real time as the player moves. Player can move up or down and I'm basically building and destroying the nodes to have just enough of them to fill the current frame (think a vertical two lane road).


What I found is that as long as ALL my child nodes were within ~2K units (pixels?) within each other then SKEffectsNode was ok. As child nodes spread further clipping began to occur around them.


I think the way it's designed is it stretches around the content of the scene until the threshold and "moves" with your content.


I'm going to try some crazy workarounds to see if I can contain my scene content within 2K of each other. It's pretty disappointing that such arbitrary restriction is placed on SKEffectNode (I read your reply about the GPU but why even send the *entire* texture to the GPU).


As for the radar – I would file it but I'm not sure how exactly.

> What I found is that as long as ALL my child nodes were within ~2K units (pixels?) within each other then SKEffectsNode was ok. As child nodes spread further clipping began to occur around them.


This is quite interesting, so to recap, I guess they try to best fit the SKEffectNodes "around" it's child nodes in a single GPU texture, and if some happend to be outside the 4Kx4K pixel range (so 2K x 2K points @2x), they just get excluded and it silently fails. It's a bit less worse than my first assumption.


So I guess the problem also appear when using a shader on SKScene, since everything is a child node, it just can't best fit everything, and as you move around with SKCamera, it just fails when you move around too much.


As to why they do it, you can only apply a pixel shader to a GPU texture, so they kinda have to. What they could do is do some tiling and not just use one huge texture.


Workaround, what about splitting your scene in chunks (you would do the tiling I mentionned above yourself) ? Do you think you can work that ? It may be a bit impractical depending on the size of your scene but you can probably optimize performances a lot. It really depends on your game type I guess.


Regarding radar, see here : https://developer.apple.com/bug-reporting/


I'll see if I have some free time this week end to file the bug too.

Screen shader in a game with a moving camera
 
 
Q