0

各頂点の Z 値だけをフレームごとに更新する必要がある地形メッシュがあります。私の現在の方法は次のようになります。

int stepping = CustomVertex.PositionNormalTextured.StrideSize / 4;

//ZPtr points to the Z value of the first PositionNormalTextured in the mesh.  
//This way we don't have to dereference ->Z for each vertex.
float* ZPtr = &(((CustomVertex.PositionNormalTextured*)
    TerrainMesh.LockVertexBuffer(LockFlags.NoOverwrite).InternalDataPointer)->Z);

float* DPtr = TerrainHeight; //point to begin scanning result
float* EndPtr = DPtr + TerrainMesh.NumberVertices; //point to stop scanning result

do { *ZPtr = *DPtr; ZPtr += stepping; } while (++DPtr < EndPtr); //copy data
TerrainMesh.UnlockVertexBuffer(); //unlock

ここで、TerrainHeight は地形の高さを表す Marshal.AllocHGlobal で作成された float 配列です。基本的に、TerrainHeight 配列全体をスキャンし、各値をメッシュ内のそれぞれの PositionNormalTextured の Z 値にコピーします。LockFlags.NoOverwrite を使用して、配列の新しいコピーを作成しないようにしましたが、LockFlags.Discard よりも高速ではないようです。

メッシュの更新には、CPU で新しい地形を計算するのと同じかそれ以上の時間がかかるため、もっと高速な方法があるはずだと思います。これについて Google で情報を見つけるのに苦労しています。頂点バッファを更新するより良い方法はありますか? 重要な場合、メッシュのサイズはユーザーが設定し、100 万を超える頂点を含めることができます (これは複数のメッシュで実現されます) が、既定の設定は 32k の頂点であり、これは単一の D3D メッシュの最大値です。

4

1 に答える 1

0

DiscardNoOverwriteフラグの影響を理解していないようです。DirectXSDKヘルプの「パフォーマンスの最適化」の「動的頂点とインデックスバッファーの使用」セクションをお読みください。動的頂点バッファーを使用しているとすると、「バッファー全体を置き換える」という意味であり、「バッファーの未使用部分に書き込みを行っているため、既に使用した部分は変更しないことを約束します」という意味です。DiscardNoOverwrite

どちらのフラグでも、新しいフレームで変更されていないものも含めて、地形頂点のすべてのコンポーネントを書き込む必要があります。

動的頂点バッファーを使用しない場合、GPUがまだ使用していると、次のフレームの頂点バッファーをロックしようとしたときにストールが発生する可能性があります。その場合、複数の頂点バッファーを使用し、地形の高さが変化するフレームごとに異なるバッファーでロック、更新、ロック解除、およびレンダリングする必要があります。また、これらすべてのバッファをすべての地形頂点データで初期化する必要があります。

メッシュのz値を独自の頂点バッファーに分離することをお勧めします-xとyの位置、法線(zが変更された場合は正しくない可能性があります)、またはテクスチャ座標を更新していないと仮定します。このようにして、 (位置zなしの)頂点バッファーをすべてのフレームにそのまま使用し、各Z値にストライドすることなく、フラグPositionNormalTexturedを使用して、最初から各フレームで動的z位置バッファーを埋めることができます。Discardストライドがなくなったので、フラットメモリコピーでそれを行うことができます。

頂点シェーダーに。を使用してz位置の値を指定しSetStreamSource( 1, ZPositionVB, ... )ます。ストリーム1からz位置の値を読み取るように頂点宣言を調整し、変換前にz位置の値を結合するように頂点シェーダーを調整する必要があります。

これの一部がC#に適していない場合は、お詫び申し上げます。

于 2012-06-23T00:43:34.463 に答える