SpriteKit SKShader flipping after SKTransition completes

170 Views Asked by At

I'm creating a space-themed game in SpriteKit and to simulate a starfield I'm using an GLSL fragment shader from ShaderToy, converted to work in SpriteKit.

To use it I simply init a clear SKSpriteNode of the same size as my scene (2048 x 1536) and apply the shader to this node.

let starField = SKSpriteNode(color: UIColor.clear, size: CGSize(width: 2048, height: 1536))
let shader = SKShader(fileNamed: "Starfield.fsh")
starField.shader = shader

The shader renders just fine and shows a nice starfield. So far, so good.

The problem occurs when I transition from a different scene using SKTransition. During the transition, the shader appears to be rasterising, and as soon as the transition is complete the whole thing flips upside down.

My transition code (doesn't appear to matter what transition or duration I use):

let gameScene = GameScene(level: level)
gameScene.scaleMode = self.scaleMode
let transition = SKTransition.fade(withDuration: 3.0)
transition.pausesIncomingScene = true
self.view?.presentScene(gameScene, transition:transition)

I've tried with a different shader and the same occurs - the starfield is one way up during the transition, and instantly 'flips' as soon as the previous scene has been cleared up. Has anyone experienced the same and knows what is going on?

I have a video of the problem, which you can see occurring at around 7 seconds:

https://youtu.be/l1lLv6MwKYU

The shader code is as follows:

#define M_PI 3.1415926535897932384626433832795

float rand(vec2 co);

float rand(vec2 co)
{
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}

void main()
{
    float size = 50.0;
    float prob = 0.95;

    vec2 pos = floor(1.0 / size * gl_FragCoord.xy);

    float color = 0.0;
    float starValue = rand(pos);

    if (starValue > prob)
    {
        vec2 center = size * pos + vec2(size, size) * 0.5;

        float t = 0.9 + 0.2 * sin(u_time + (starValue - prob) / (1.0 - prob) * 45.0);

        color = 1.0 - distance(gl_FragCoord.xy, center) / (0.9 * size);
        color = color * t / (abs(gl_FragCoord.y - center.y)) * t / (abs(gl_FragCoord.x - center.x));
}
    else if (rand(v_tex_coord) > 0.996)
    {
        float r = rand(gl_FragCoord.xy);
        color = r * (0.25 * sin(u_time * (r * 5.0) + 720.0 * r) + 0.75);
    }

        gl_FragColor = vec4(vec3(color), 1.0);
    }

:

0

There are 0 best solutions below