ねこでじ(Nekodigi)

Nekodigi’s diary

学習中の気づきをまとめています。応援よろしくお願いします

【Processing】水の浸食をシュミレーションし、フォトリアルな雪山を作る。

成果物

www.youtube.com
予想以上の美しさにちょっと驚きました。今回は、CodingAdventureで紹介されていたHydraulic ErosionをProcessingで実装していました。いくつかぶつかったポイントをまとめておこうと思います。

コード

仕組み

もとにしたサイトはこちらです。
www.youtube.com
大まかに説明すると、水の流れを勾配に沿って動く粒子を使って再現ていて、水中の堆積物が容量より多ければ堆積し、少なければ浸食する仕組みになっています。
それでは、次に細かい部分を説明します。
まず、スタートした粒子は勾配に沿って移動します。高さの変化をΔhとします。坂を下ったときは符号は-です。
次に、-Δh×水の速度(speed)×水量(water)を求め容量を決めます。なぜこの式になるかというと、傾きが急で、流れが速く、水量が多ければたくさん堆積物があっても堆積しないからです。

  • 堆積物が容量をオーバーしていた場合→堆積

 オーバーしていた分×堆積比率分だけ水中の堆積物の量を引き、その分周囲の頂点の高さを上げます。

  • Δh>0(坂を上ったとき)→堆積

 坂を上がった分、水中の堆積物を減らす。

  • 堆積物が容量より少なかった場合→堆積

 容量が足りない分×浸食比率分だけ、堆積物の量を足し、その分、次の式で求められる重みに従って頂点の高さを下げます(高負荷なので配列に保存した計算結果を使用しています)。粒子の浸食範囲内の周りの頂点の重みを次の式で決めます。 (1-距離/浸食範囲)/(補正前の重みの合計)
正確には、数値が既定の範囲に収まるように様々な条件分岐が行われていますが、ベースの部分はそこまで難しいものではないです。また、実際のコードでは、粒子の座標から周囲の頂点の座標を線形保管してデータを求めているので少しややこしいです。
入力データは、0~1までの間に正規化した方が結果が良くなるので注意してください。