私は OpenGL 3D レンダラーに取り組んでいます。Java と JOGL API を使用しています。現在、遅延レンダラーのパフォーマンスを微調整しようとしています。このために、貴重な CPU サイクルを食い尽くしているものを確認するために VisualVM プロファイラーを使用し、OpenGL 関数呼び出しを追跡するために gDEBugger も使用しています。現時点では、20 ~ 30 個のライトしか存在しない場合でも 30 FPS 未満に低下しています (また、照明が必要な実際のメッシュの数が非常に少ない場合でも)。また、シャドウ マッピングや法線マッピングなどもまだ追加していません。
これは、現時点での外観です (41 個のライトが 20 FPS のみ)。
VisualVM では、ほとんどのCPU時間がネイティブjogamp.opengl.windows.wgl.WGLUtil.SwapBuffers
メソッドで費やされていることに気付きました。ただし、この情報がシェーダーの実行時間に関連しているのか、何らかの形で関連しているのかはわかりません。呼び出しの実行時間glDrawArrays
はごくわずかです。これは、このメソッドが GPU に呼び出しを発行するだけであり、戻る前に呼び出しが終了するのを待たないという事実を裏付けています。アプリケーションの時間のほとんどがその関数呼び出しに費やされているのはなぜですか?
さらに奇妙なのは、3 ~ 4 個のライトがある場合、60 FPS で実行することです。その数を 20 に増やすと、数は 20FPS に低下します。1000 ~ 1100 個のライトを追加しても、約 10 FPS が得られます。何故ですか?ライトの計算は加算的であるため、ライトが 1000 の場合は、ライトが 20 の場合よりも多くのフラグメント シェーダーがピクセルごとに実行されるはずです。3 ~ 4 個のライトから 20 個のライトにジャンプすると、なぜこのようにパフォーマンスが大幅に低下するのでしょうか?
そして、私の質問のパート II: 前に言ったように、OpenGL 呼び出しのプロファイリングに gDEBugger を使い始めましたが、残念ながら、実行に最も時間がかかるものを正確に判断する方法を見つけることができないようです -どの関数が最も多く呼び出されるかに関する情報のみを取得します。冗長な状態変更などを探し出すときに役立ちますが、私がいる段階では、レンダラーの速度を低下させる大きな問題があると確信しています。
フラグメントシェーダーの実行時間を追跡し、どのフラグメントのどの計算が最も長くかかるかを正確に確認する信頼できる方法を知っている人はいますか? nVidia nSight が優れたグラフィックス デバッグ機能を提供していることは知っていますが、それらのほとんどは DirectX アプリケーションでしか利用できません。