2016-09-06 31 views
1

いくつかのスプライトが動き回っているアプリケーションでは、SKShaderを使用して水分の影響を受けています。このチュートリアルMaking a Pixel Shader for iOS8 with Sprite Kitに基づいて、私はエフェクトを作成しましたが、フレームレートがシミュレータで下がり、iPhone 5でメモリの問題が発生しました。SKShaderを使用するとパフォーマンスが低下する

私のコードはGameSceneから 以下に示します。

override func didMoveToView(view: SKView) { 
     super.didMoveToView(view) 

     // MARK: BACKGROUND IMAGE & SHADER 

     let backgroundImage = SKSpriteNode(imageNamed: "Background") 
     backgroundImage.size.width = frame.size.width 
     backgroundImage.size.height = frame.size.height 
     backgroundImage.position = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame)) 
     backgroundImage.zPosition = -1000 
     addChild(backgroundImage) 

     let shaderContainer = SKSpriteNode(color: SKColor(red: 1, green: 1, blue: 1, alpha: 0), size: (CGSizeMake(frame.width, frame.height))) 
     shaderContainer.position = CGPointMake(self.frame.size.width/2, self.frame.size.height/2) 
     shaderContainer.zPosition = 1000 
     addChild(shaderContainer) 

     let shader = SKShader(fileNamed: "shader_water.fsh") 
     shader.uniforms = [ 
      SKUniform(name: "size", floatVector3:GLKVector3Make(Float(self.frame.size.width), Float(self.frame.size.height), 0)), 
     ] 
     shaderContainer.shader = shader 

.fshファイルはチュートリアルからまっすぐに取られます。

void main(void) 
{ 
    float time = u_time * .5; 
    vec2 sp = gl_FragCoord.xy/size.xy; 
    vec2 p = sp * 6.0 - 20.0; 
    vec2 i = p; 
    float c = 1.0; 
    float inten = .05; 

    for (int n = 0; n < 5; n++) 
    { 
     float t = time * (1.0 - (3.5/float(n+1))); 
     i = p + vec2(cos(t - i.x) + sin(t + i.y), sin(t - i.y) + cos(t + i.x)); 
     c += 1.0/length(vec2(p.x/(sin(i.x+t)/inten),p.y/(cos(i.y+t)/inten))); 
    } 

    c /= float(5); 
    c = 1.55-sqrt(c); 
    vec3 colour = vec3(pow(abs(c), 15.0)); 

    gl_FragColor = vec4(clamp(colour + vec3(0.0, 0.17, 0.3), 0.0, .5), 0.3); 
} 

誰もが起こっているかもしれないものと私はシェーダがより効率的に仕事を得ることができる方法を知っていますか?

答えて

2

フラグメントシェーダの計算全体がu_time & gl_FragCoordに基づいているため、同じ計算を頂点シェーダに移動することができます。シェイダーのパフォーマンスを向上させるための基本的なヒント

  • は頂点ごとに、すべての計算を行うと、シェーダでフラグメントの計算ごとに(あなたのケースでは、forループ)
  • 避けループを避けるため、GPUは、応答のための
+0

感謝をループ で良いではありません。 SpriteKitは頂点シェーダを持っていないようです(この回答から別の質問へ... http://stackoverflow.com/questions/29597314/vertex-shader-in-spritekit)。頂点ごとの計算を移動するか、forループを削除する方法をいくつか考えていますか?チュートリアルのフラグメントシェーダーは、https://www.shadertoy.com/view/MdlXz8に基づいているようです。 –

+0

SpriteKitは頂点シェーダーを許可していないようですので、唯一の選択肢は、それが遅すぎるのではなく、 OpenGL ES 2.0を使用してください。シェーダを最適化する方法はたくさんありますが、まず実行可能なvertとfragシェーダを実装する必要があります。 – codetiger

+0

新しい環境への移行は、水面のイメージ効果のために劇的なようです。私はタイルサイズを増やして、反射効果の「弱められた」バージョン(反射が少ない)を作り出すことができるかどうか、CPUオーバーヘッドを大幅に減らすことができるかどうかを考えました。私はフラグメントシェイダーでそれをどのように変更するのか分かりません。 –

関連する問題