Я создаю космическую игру в SpriteKit и для имитации звездного поля я использую фрагментный шейдер GLSL из ShaderToy, преобразованный для работы в SpriteKit.
Чтобы использовать его, я просто запускаю очисткуSKSpriteNode того же размера, что и моя сцена (2048 x 1536), и примените шейдер к этому узлу.
let starField = SKSpriteNode(color: UIColor.clear, size: CGSize(width: 2048, height: 1536))
let shader = SKShader(fileNamed: "Starfield.fsh")
starField.shader = shader
Шейдер рендерится очень хорошо и показывает хорошее звездное поле.Пока все хорошо.
Проблема возникает, когда я перехожу из другой сцены с помощью SKTransition.Во время перехода шейдер выглядит растеризованным, и как только переход завершен, все переворачивается вверх ногами.
Мой код перехода (не важно, какой переход или продолжительность я использую):
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)
Я пробовал с другим шейдером, и то же самое происходит - звездное поле находится на один путь вверх во время перехода и мгновенно «переворачивается», как только предыдущая сцена была очищена.Кто-нибудь испытывал то же самое и знает, что происходит?
У меня есть видео проблемы, которое вы можете увидеть примерно через 7 секунд:
https://youtu.be/l1lLv6MwKYU
Код шейдера выглядит следующим образом:
#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);
}
: