2

私は最近、理想的には LIDAR キャプチャからの地形データ ポイントを視覚化し、それらを約 30 fps で連続して表示できるポイント クラウド プレーヤーに取り組んでいます。しかし、私は PCI-e IO によって壁にぶつかったようです。

フレームごとに行う必要があるのは、メモリに保存されている大きなポイント クラウドをロードし、高さによるカラー マップを計算し (Matlab のジェット マップに似たものを使用しています)、データを GPU に転送することです。これは、ポイントが 100 万未満のクラウド キャプチャでうまく機能します。ただし、約 200 万ポイントで、速度が低下し始め、毎秒 30 フレームを下回ります。これは大量のデータであることを認識しています (ポイントあたり 200 万フレーム * [ポイントあたり 3 フロート + カラー ポイントあたり 3 フロート] * フロートあたり 4 バイト * 1 秒あたり 30 フレーム = 1 秒あたり約 1.34 ギガバイト) 。

現在、レンダリング コードは次のようになっています。

glPointSize(ptSize);
glEnableClientState(GL_VERTEX_ARRAY);
if(colorflag) {
    glEnableClientState(GL_COLOR_ARRAY);
} else {
    glDisableClientState(GL_COLOR_ARRAY);
    glColor3f(1,1,1);
}
glBindBuffer(GL_ARRAY_BUFFER, vbobj[VERT_OBJ]);
glBufferData(GL_ARRAY_BUFFER, cloudSize, vertData, GL_STREAM_DRAW);
glVertexPointer(3, GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, vbobj[COLOR_OBJ]);
glBufferData(GL_ARRAY_BUFFER, cloudSize, colorData, GL_STREAM_DRAW);
glColorPointer(3, GL_FLOAT, 0, 0);
glDrawArrays(GL_POINTS, 0, numPoints);
glDisableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);

vertData と colorData のポインターはフレームごとに変更されます。

私ができるようにしたいのは、後でフレームあたり最大 700 万ポイントに達する可能性のある大きな点群を使用する場合でも、最低 30 フレーム / 秒で再生できるようにすることです。これは可能ですか?それとも、それらをグリッドにして高さマップを作成し、何らかの方法で表示する方が簡単でしょうか? 私はまだ3Dプログラミングにかなり慣れていないので、アドバイスをいただければ幸いです。

4

5 に答える 5

7

可能であれば、1D テクスチャを使用してカラー マップを実装します。3 つの色の代わりに 1 つのテクスチャ座標のみが必要になり、頂点も 128 ビットに揃えられます。

編集: カラーマップからテクスチャを作成し、glColorPointer の代わりに glTexCoordPointer を使用する必要があります (もちろん [0, 1] の範囲でテクスチャ座標の頂点カラー値を変更します)。線形補間された 6 テクセル カラーマップは次のとおりです。

// Create texture
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_1D, texture);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

// Load textureData
GLubyte colorData[] = {
    0xff, 0x00, 0x00,
    0xff, 0xff, 0x00,
    0x00, 0xff, 0x00,
    0x00, 0xff, 0xff,
    0x00, 0x00, 0xff,
    0xff, 0x00, 0xff
};
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 6, 0, GL_RGB, GL_UNSIGNED_BYTE, colorData);
glEnable(GL_TEXTURE_1D);
于 2010-08-02T23:32:07.763 に答える
4

私はopenglについて何も知りませんが、データ圧縮はここでの自然な回避策ではないでしょうか? 整数型または 16 ビット浮動小数点数はサポートされていませんか? また、ポイントあたり 3 つのフロート以外の色表現はありますか?

于 2010-08-02T23:05:34.257 に答える
3

遅延に対処したい場合は、VBO を 2 倍 (またはそれ以上!) バッファリングし、ジオメトリを 1 つのバッファに転送し、別のバッファからレンダリングすることができます。

while(true)
{
    draw_vbo( cur_vbo_id );
    generate_new_geometry();
    load_vbo( nxt_vbo_id );
    swap( cur_vbo_id, nxt_vbo_id );
}

編集:コンポーネントごとに 1 つの VBO を使用する代わりに、頂点をインターリーブすることもできます。

于 2010-08-03T00:19:24.767 に答える
1

あなたはそれがI/Oバウンドだと言います。これは、プロファイルを作成し、I / Oの待機に50%以上の時間を費やしていることを意味します。

もしそうなら、それはあなたが集中しなければならないことであり、グラフィックスではありません。

そうでなければ、他の答えのいくつかは私には良いと思います。とにかく、プロファイル、推測しないでください。これが私が使っている方法です。

于 2010-08-03T01:05:31.113 に答える
0

いくつかのポインタ:

  • グラフィックカードにできるだけ多くのデータを保存し、本当に必要なものだけをロードします(かなり明白です)
  • ツリー (kd または octtree) で lod レベルを使用し、可能な限り前もって計算する
  • ディスク上の圧縮も、io のボトルネックを克服するために役立ちます。
于 2010-08-03T12:21:54.793 に答える