流れるGPU計算水


15

私は土木工学のバックグラウンドを持ち、水理および水文解析を定期的に実行しています。彼らはそのようなことのために学位を売りますが、それは実際にロケット科学ではありません。私は最近、GPUの地形に水文および油圧プロセス全体を実装することを思いつきました。コンピューティングシェーダーを習ったのはごく最近のことなので、現在、並列GPUワークフローを設計するよりも、エンジニアリングの方が優れていることにこだわっています。

次の式を使用して、降雨イベント中に生成された水の量を計算できます。
Q (CF/S) = c * I (in/hr) * A (acres)

私は、最初の領域の「面積」の計算を超えて移動するのが困難です。

現在の実装の概要:

  1. 地形は、1ユニット間隔の頂点の規則的なグリッドです
  2. ハイトマップには、頂点ごとに1つのR32高さ値が含まれます
  3. 現在、私は4つの基本方向(対角線なし)のフローのみを許可しています
  4. Texture2D [int]を、既に分析した頂点のステンシルとして使用しています

現在のアルゴリズム:

  1. 地形ツールがアクティブで、現在はそうではないとき...
  2. 「ステンシル」をクリアします。
  3. 標高が最も低い地形全体をスキャンします。
  4. その単一ポイントは、CS_Floodへの初期入力です。
  5. CS_FloodはX軸パスを作成します。
  6. 各入力頂点は、X方向とX +方向の両方に最大2048回投影されます。
  7. OOB座標で隣接する頂点を見つけると、この方向の地形のエッジが示されます。CurrentPointがBoundaryPointsバッファーに追加され、その方向の投影ループが終了します。これは簡単で、毎回うまく機能しました。
  8. 高さ> =現在の頂点の高さを持つ隣接する頂点は、ステンシルでマークされ、NextPassバッファーに追加されます。
  9. 高さ<現在の頂点の高さを持つ隣接する頂点は、リッジのピークを示し、投影ループを終了します。塗りつぶしの将来の反復があります、それの「裏」側まで、尾根のベースの周りに流れ、同じ尾根をもう一度検出します。
  10. この目的のために、複数回検出されたピーク/リッジポイントはBoundaryPointにはなりません
  11. 一度だけ検出されたピーク/リッジポイントはBoundaryPointsに追加され、その方向の投影ループは終了します。
  12. CS_Floodは、X軸パスによって生成されたポイントを入力として使用して、同じコードでZ軸パスを作成します。
  13. 現在、CS_Floodは2つの方向を無期限に交互に継続します。最終的に、CS_Floodが完了し、NextPassバッファーが空になるたびに、ループ全体を終了します。

理想的には、その時点で、BoundaryPointsには、自然の排水分割で発生する各頂点が含まれます。境界内に着弾した水滴は、最終的に同じ低地点に流れます。水滴が着地すると、境界は「どこか他の場所」に移動します。

次に:

  1. ステンシルをクリアせずに、地形を再スキャンして、ステンシルのない最も低い頂点を探します。
  2. CS_Floodを繰り返します。
  3. ステンシルがいっぱいになるまで(または同様の)を繰り返します。

3Dはこれらの色を認識するのが困難です。これは、積分高度で等高線を示します
:(エッジ近くのバームに囲まれた穴) エッジバームホール

頂点を越えて排出する約10のユニークな方法があります。それぞれにユニークな色を与えます:(
目に見える円形のツールマーク、「リッジ」がきれいに表示されます) ここに画像の説明を入力してください

これは、CS_Flood、境界、またはそれ以外で生成されたすべてのポイントをPOINTLISTとして表示します。 ここに画像の説明を入力してください

アルゴリズムは常に ほとんど機能します。時には、それも正しく動作します。その他の場合、アルゴリズムは正しい形状に明確に含まれていますが、無期限にポイントを出力し続けます。3番目のスクリーンショットに見られるように、時々混乱します。私が見落としていた別の状況/要因がなければなりません。私の見落としや、問題を攻撃するためのより簡単な方法および/またはよりエレガントな方法の提案を見つけるのに役立つことを感謝します。

欠けている点

MissingPoint!検出されたすべての新しいBoundaryPointをNextPassバッファーに追加するアルゴリズムを帯域支援することで含めることができます。次のパスでは、そのバンドエイドによって生成されたポイントの99%がわずかなGPU時間を浪費し、どこにも行けず何もしないと判断します。最初のパスでは、LowestPointを他のNextPassポイントと一緒に送信することも、この特定のシナリオを処理します。

私はそれがもっともらしいことを知っています、そして、十分な時間を与えられれば、私が望むことをするのに十分それをバンドエイドすることができます。できれば、より良く、よりスマートに、より速くそれをしたいのですが、まだ十分な経験がありません。


つまり、地形のすべての水が流出する場所を計算したいということですか?
EvilTak

@EvilTak、私は良いアルゴリズムに落ち着いたと思うが、説明する経験がない「奇妙なもの」がまだ得られている。あなたはパラレルGPU'ingが得意な場合は、チェックアウトしてください:gamedev.stackexchange.com/questions/118556/...を
ジョン

回答:


1

ドロップが頂点を「試行」したとき、ステンシルはInterlockedExchange「元の値」を使用してマークされ、既にステンシル化されているかどうかを判断しました(単に上書きしましたが)。

私が思いついた最高のアルゴリズムは、洪水に「スクラッチパッド」と単一のルール「下り坂を流れない」(高さ以上)を与えました。これにより、複雑なテストのほとんどすべてが不要になりました。一般に山/尾根の上を流れないのが得意ですが、隣接する頂点が「平坦」であるため、山/尾根に沿って流れます。これにより、時折、dropsが尾根線をこっそり通過できるようになります。

ここに画像の説明を入力してください

「遠すぎる」ポイントのそれぞれは、「流されて」、排水エリアに「流れ込む」(1で停止)か、流れない(0で停止)。「nots」は破棄され、修正されたスクラッチパッドは「final」にコピーされます。ファイナルが既にステンシルされている場合、スクラッチパッドは破棄されます。(将来:これらの衝突は集合的に現在の排水エリアの外側の境界を表す必要があります。)

10FPSの場合:

ここに画像の説明を入力してください

「nots」は赤で表示され、大きな領域がファイナルにコピーされて緑になったら、残りの非ステンシル領域についてアルゴリズムが繰り返されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.