2016-11-04 11 views
1

アプリケーションが60fps前後でスムーズに動作していても、新しいノードが画面に表示されたときにSceneKitアプリ(メタルを使用)で吃音が発生しました。新しいノードが表示されたときにSceneKit app stutters

物が破壊され、何かが破壊された場所にパワーアップが現れるゲームを想像してください。私は、吃音がパワーアップに関係していることを確信しています。なぜなら、物事がちょうど破壊されたときに(そしてシーンから取り除かれて)起きないからです。 SceneKitビューのプリロードメソッドを使用してノードをプリロードし、そのシーンを完了ハンドラ内でのみシーンに追加します。 私はそれらを表示する必要があるよりずっと前にカメラの上に追加し、時間が来たら私はそれらを正しい位置に移動します。 私は、1つの変更(破棄されたアイテムのノードを削除し、その場所でパワーアップを移動する)がフレームごとに行われるようにキューイングのメカニズムを実装しました。

ただし、電源がオンになっても吃音が(時には起こらない)場合があります。私はSceneKitが何かをやっているのかどうかは、ノードが初めて表示されたときだけ(たとえプリロードされていても)疑問に思っています。どんなことが起こっても吃音を引き起こすのに十分だと思われますが、XCodeパフォーマンスメーターがそれを示すには短すぎます。あらゆるフレームには多くのアイドルタイムがあり、CPUとGPUは決して限界に近づいていません。

複雑なジオメトリや巨大なテクスチャに関連しているとは思えません。なぜなら、均一な色で単純なキューブを使用すると、それでも問題が発生するからです。

ここで何が起こっているのか、これをどのように追跡することができますか?

答えて

0

私は自分で理由を見つけました。同じ問題が発生した場合に備えて、皆さんと共有したいと思います。

SceneKitがシーンの中でやっている神秘的な仕事は、さまざまなノードのシェーダーを再コンパイルすることです。 Appleはこれを確認しませんでしたが、SceneKitには、それぞれのノードを意図したとおりにレンダリングするのに十分複雑な最も効率的なシェーダを常に使用する方針があります。つまり、エフェクト、マテリアルプロパティまたは光源を追加するたびに、より複雑なシェーダをコンパイルします。また、ライティング計算の複雑さが増した理由を取り除くと、シンプルなシェーダに置き換えられます。

これは常に最高のパフォーマンスを得るという点で優れていますが、それはまた、私が経験したことである欠点を持っています。シェーダの再コンパイルには時間がかかり、CPUに負担がかかり、GPUに新しいバージョンのシェーダを待たせることになります。結局のところ、ほとんどの時間が完全にスムーズに実行されていても、アプリは途切れてしまいます。

これを回避する最も簡単な方法は、SCNProgramを使用して独自のコードでSceneKitシェーダを置き換えることですが、これによってSceneKitが提供する快適性のほとんどが失われます。私が望んでいたものではないので、私は次のアプローチで終わりました:

SceneKitは、最初にシーンを黒いオーバーレイで覆って後で見える可能性のあるすべてのノードのシェーダを最初にコンパイルし、カメラの前にあるすべてのノードを追加してから、正しい位置に移動してから、カバーレイヤをフェードアウトします。 また、私はいつも必要ではないエフェクトを完全にオフにすることによって再コンパイルを避けることもできます(例えば、ライトをオフにするには、強度を0ではなく0.1に変更します)。これにより、SceneKitは常に同じシェーダを保持し、吃音を回避します。

これもAppleによって確認されていませんが、これまでのところ動作していたので、私の仮定は正しいと思います;-)。

関連する問題