2

高さマップとしてモデル化された世界の地面にあるOpenGLシーンのマウス座標を追跡したいと思います。現在、ハードウェアテッセレーションのような派手なものはありません。この質問はオブジェクトの選択に関するものではないことに注意してください。

現在、私は次のことを行っていますが、リードバック操作のためにパフォーマンスが明らかに低下しています。

  • 世界をレンダリングする(地面)
  • マウス座標での深度値を読み戻します
  • シーンの残りの部分をレンダリングします
  • バッファを交換して次のフレームをレンダリングします

地面の前にオブジェクトがない状態で地面の深さの値が必要なため、リードバックは2つのレンダリングステップの間にあります。これは、次のコマンドを使用して実行されます。

GLfloat depth;
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);

私のアプリケーションでは、フレームレートを1秒あたり60フレームに制限しています。リードバック操作なしでシーンをレンダリングすると、CPU使用率は5%未満になりますが、リードバックを実行すると、シーンのレンダリングやゲームモデルの更新にはあまり力を入れていませんが、約75%に増加します。またはそのようなもの。

一時的な解決策は、マウスの下のピクセルの深度値をキャッシュし、5フレームまたは10フレームごとにのみ更新することです。これにより、CPU使用率が10%未満に戻ります。しかし、明らかに問題の最善の解決策になることはできません。

ピッキング(サーフェス上の(浮動小数点)座標が必要なため、オブジェクトピッキングではない)を効率的に実装するにはどうすればよいですか?

バックバッファの代わりにフロントバッファの深度値を読み戻すことをすでに考えていましたが、その方法をグーグルで調べると、glRead*メソッドについて不満を言う人だけが最善の方法であることがわかります。しかし、(glRead *を使用して)何かを読まずに(ピッキングを行う)何かを読むにはどうすればよいですか?

よくわかりません。他の人はどのようにピッキングを実装しますか?


まったく異なるアプローチは、ソフトウェアで世界表面ピッキングを実装することです。カメラから「深さまで」3D光線を再構築することは大したことではありません。これは、ターゲットピクセルでレンダリングされる空間内のポイントを表します。次に、交差アルゴリズムを実装して、サーフェスの最前面のポイントを見つけることができます。

4

1 に答える 1

3

通常、CPUに実装します。ハイトマップ座標でピッキングレイを見つけ、ハイトマップ全体で単純なライントレースを実行します。これは線画と非常によく似ています。交差する各セルで、三角形分割に使用した三角形に対してテストします。

完了するまでGPUからの読み取りを避けることが重要です。通常、描画コマンドを数フレーム先にスケジュールするため(GLはこれを自動的に実行します)、これは、結果のみを取得するか、GPUが追いつくまでCPUを停止することを意味します。しかし、このような単純なことにはそれをしないでください!

于 2012-09-17T16:28:21.567 に答える