iOS9 より、SpriteKit が Metal を使ってレンダリングされるようになりました。
その影響か、いくつかの不具合があるようです。
下記の内容は iOS9.1 で確認しています。
フラグメントシェーダでエラーが出る
シェーダの言語仕様の違いか、下記のエラーが発生します。
error: use of undeclared identifier 'gl_FragCoord'
回避策は、後述の「OpenGL を使ってレンダリングを行う」しか無さそうです。
なお、関数の外に定数を定義すると、下記のエラーが発生します。
error: global variables must have a constant address space qualifier
こちらは、関数内に定数定義を移せば発生しなくなります。
フラグメントシェーダの Uniform 変数 u_sprite_size が使えない
u_sprite_size が常に (0, 0) で来るため、使い物になりません。。。
対策としては、下記のように自力でスプライトのサイズを計算し、Uniform 変数として渡します。
let spriteSize = node.calculateAccumulatedFrame()
let uniformSpriteSize = SKUniform(name: "sprite_size", floatVector2: GLKVector2Make(Float(spriteSize.width), Float(spriteSize.height))
SKEffectNode で CIGaussianBlur を使うと、スプライトの位置がずれることがある
SKEffectNode で CIGaussianBlur を使うと、inputRadius の値によって子ノードのスプライトの位置がずれることがあります。
こちらも後述の「OpenGL を使ってレンダリングを行う」で回避するか、CIBoxBlur など他のブラーで代用するしかなさそうです。
Tips: iOS9/SpriteKit で OpenGL を使ってレンダリングを行う
リファレンスを読むと、SceneKit には OpenGL/Metal どちらでレンダリングを行うかを指定できるのですが、SpriteKit には見当たりません。
別の方法として、Info.plist
に以下の設定を行うことで、OpenGL によるレンダリングに変更することができます。
PrefersOpenGL: YES
参考: https://developer.apple.com/library/ios/qa/qa1904/_index.html