2016-07-21 8 views
1

iは深さだけこのようないくつかのモデルをレンダリングしたカラーアタッチメントを追加すると3倍の減速が発生するのはなぜですか?

m_fbo = new globjects::Framebuffer(); 
depthBuffer = globjects::Texture::createDefault(); 
depthBuffer->storage2D(1, GL_DEPTH_COMPONENT32F, size, size); 
m_fbo->attachTexture(GL_DEPTH_ATTACHMENT, depthBuffer); 

m_fbo->bind(); 
... draw all the things 

を今、私はこのようにそれに色の添付ファイルを追加する場合:属性バッファの形式に応じて、

m_fbo = new globjects::Framebuffer(); 
depthBuffer = globjects::Texture::createDefault(); 
depthBuffer->storage2D(1, GL_DEPTH_COMPONENT32F, size, size); 
m_fbo->attachTexture(GL_DEPTH_ATTACHMENT, depthBuffer); 

attributeBuffer = globjects::Texture::createDefault(); 
attributeBuffer->storage2D(1, <format>, size, size); 
m_fbo->attachTexture(GL_COLOR_ATTACHMENT0, attributeBuffer); 

m_fbo->bind(); 
... draw all the things 

を、レンダリング時間は2.6msから5ms(R8、RG8)、8.5ms(RGB8、RGBA8、R32F)または14.5ms(RG32F、RGBA32F)(OpenGLタイマークエリで測定)になりました。

私はフラグメントシェーダを変更していないので、そのカラーバッファに書き込むための追加の値は計算しません。もし私がその文をattachTextureとコメントアウトすると、レンダリング時間は再び下がります。

手元のテクスチャは2Kx2Kのシャドウマップアトラスです。プログラムは、モデルをテッセレーションし、各三角形をポイントに変換し、そのポイントをgl_PointSize = 1で、そのアトラス内の無作為に選ばれた64x64タイルにレンダリングします。テッセレーションとジオメトリシェーダは非常に重いので、これはバンド幅かフィルレートの境界ではないと思います。私が1つの大きなシャドーマップに複数の小さいものを描画するのではなく、このスローダウンははるかに小さくなります(1.9から2.1ms)。 (2.3ms 1.9)

iが手動でジオメトリシェーダでimageStoreとテクスチャーに属性を書き込み、色アタッチメントを使用しない場合、減速は同様に妥当である

にも、この減速が不思議消えnsightでトレースを開始すると、これをプロファイルできなくなります。

これはなぜ起こるのでしょうか?

私は750 Tiを使用しています。

答えて

1

ほとんどのOpenGLパフォーマンスの問題と同様、実装に依存します。したがって、実際の実装がどのように機能するかわからない限り、推測することしかできません。

  1. 通常、GPUは深度のみのレンダリングに最適化されています。カラーアタッチメントを追加しているので、深度のみのレンダリングはもうやっていません。
  2. あなたのカラーアタッチメントフォーマットはGL_R32Fです。この形式は、通常の古いGL_RGBA8形式よりもレンダリングが遅くなる可能性が最も高いです。
  3. ランダムに選択した64x64シャドウマップに切り替えるたびにレンダーターゲットを変更すると、これは実際には遅いです。レンダーターゲットを変更するのは非常にコストがかかる操作ですが、その周りにはいくつかの方法があります。このプレゼンテーションの29ページを参照してください。http://http.download.nvidia.com/developer/presentations/2005/GDC/OpenGL_Day/OpenGL_FrameBuffer_Object.pdf
  4. 私はあなたを正しく理解していれば、1ピクセルの三角形をたくさんレンダリングしています。これは非常に遅いです。これは、GPUが2x2ピクセルのグループでピクセルをラスタライズするためです。 1ピクセルだけがレンダリングされたとしても、ハードウェアはシェーダを4回実行してから3ピクセルを破棄します。レンダリングしているすべてが1ピクセルの三角形であれば、ラスタライズのパフォーマンスの3/4を無駄にすることになります。

なぜ奥行きの添付ファイル形式GL_DEPTH_COMPONENT32Fを使用しているのですか?ほとんどのGPUは32ビット深度バッファをサポートしていません。通常24ビット。 GL_DEPTH_COMPONENT24またはGL_DEPTH_COMPONENT32を代わりに使用してみましたか?

これは非常に特有の問題です。あなたのGPUドライバをアップデートしようとしましたか?

+0

1:確かに、私はパフォーマンスのヒットは期待していましたが、これは大きなものではありません。 2:私は他のフォーマットを試しましたが、何の効果もありません。 3:すべてのシャドウマップがこの1つの大きなアトラスにあり、切り替えは伴いません。 4:私は点を描画してgl_pointSizeを1に設定します。ラスタライズのパフォーマンスを無駄にする点は依然として正しいかもしれませんが、これもカラーの添付がない場合です:) 5.特別な理由はありません。私は24ビットを試してみるだろうが、カラーバッファの問題に影響するのではないか... ...? – karyon

+0

ああ、はい、私はドライバを更新しました:) – karyon

+0

深度バッファのヒントは単なる一般的なヒントでした。これは非常に奇妙な問題であるようです。パフォーマンスを正しく測定していますか?どのようにシャドーマップのある領域にレンダリングしていますか?ビューポートを変更しますか? – Tara

関連する問題