LoginSignup
4
5

More than 5 years have passed since last update.

iOS9のSpriteKit/SKShaderの不具合

Posted at

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))

参考: http://stackoverflow.com/questions/31492404/spritekit-shader-crash-ios-9-skdefaultshading-gl-fragcoord

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

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5