地形エディタをつくる

公開 更新

環境:Claude Code (Opus4.8)

表示は軽いシンプル表示、PBR、天球を切り替える。PBR では太陽の方向、光量、環境光、影を調整でき、天球では大気散乱とレイマーチ式のボリューム雲を表示する。

概要

ハイトフィールドを中心にした、ノードベースの地形エディタを試作してみた。GeoGenの開発が止まってしまったことと、コーディングエージェントのおかげで自前で理想のエディタをつくれるようになった。とはいえ「いい感じに作って」とAIに丸投げしてもまだ十分なものは作れないので、地形生成のアルゴリズムを同時並行で勉強している。

地形生成の考え方は、以前書いた地面のレイヤーについての記事が土台になっている。岩、土、植生、砂礫の分布を、傾斜や標高、水の流れといった共通の条件から組み立てたい。

仕様

Windows 向けのデスクトップアプリで、言語は C++20、描画は DirectX 12、UI は Dear ImGui、ノードグラフには imgui-node-editor を使っている。地形は、平面上の各位置に高さを持つハイトフィールドとして扱う。単位は 1 unit = 1 m で、ノードの大きさや堆積する厚みも、この実寸を基準に調整する。

ノードベース

起点になるのは、画像を読み込む Import Heightmapノード。読み込んだハイトマップは、地形キャンバスの中で幅と奥行き、高さをメートルで指定する。

そこへ浸食や堆積のノードをつなぎ、地形の形を変えていく。たとえば、土台に浸食をかけ、岩を加え、土砂や表土を載せるという順序で組む。下流のノードがリアルタイムで上流の結果を受け取るので、土台を調整しながら、その先の堆積や色分けまで確認できる。

浸食と堆積

浸食にはDroplet Erosionノードを使う。地表を移動する水滴粒子によって削りと土砂の運搬を計算する。

堆積は、どこに何を載せるかでノードの役割を分けた。

ノード役割
Crumbling指定した範囲から崩落粒子を発生させ、低い方向へ流して岩屑を堆積させる
Sediment土砂を滑らせ、溝や谷底を埋めるように堆積させる
Soil表土をかぶせ、緩斜面では残し、急斜面では滑らせて岩盤を露出させる
Snow地形の形に沿って積雪面を作る

同じ土を載せる処理でも、谷を埋める Sedimentノードと、地表を覆う Soilノードでは結果が違う。Soilノードは土の厚みだけでなく、どこが覆われたかをマスクとして取り出せるので、その後の色分けにも使える。

岩と散布

Rockノードは岩を散布するノードで、岩の形状や向き、配置する範囲を調整する。基本的に地形全面に使って、陸が出来た頃の岩だけの状態にする。

Scatterノードは半球や円錐を散布する汎用ノード。いまは植生の分布を確認するための仮の形状としても使っている。専用の植生ノードで木や草を生成するところは、今後の課題。

マスクで分布を決める

地形の形とは別に、処理をかける場所や色を付ける場所をマスクで扱う。

Mask Heightノードは標高、Mask Slopeノードは傾斜角、Mask Curvatureノードは尾根や谷の曲がり方からマスクを作る。Mask Fluvialノードは流量の累積や粒子の通過密度を使い、水が集まる川筋を拾う。

目指しているのは、岩、土、植生、砂礫を同じ地形条件から決める流れ。土が安定して載る場所を植生の候補とし、急斜面や強い流水のある場所では岩や砂礫を増やす、といった関係をノードを時系列でつなぐことで表現したい。

色を付けてプレビューする

多くの地形エディタのようにカラーグラデーションで地形の色を作成する。

Colorize はマスクとグラデーションからカラーテクスチャーを作る。標高による色の変化、岩ごとの色のばらつき、土や雪の被覆範囲などを使って、形状と対応した色分けができる。

最終的な出力を考えると、この色が最終出力になるわけでなく、あくまで目安なのでこの手法を追求しすぎるのもどうかなと思う。

これから

いまは地形の土台を読み込み、浸食、堆積、被覆、色分けを組み合わせて書き出すところまでが動いている。ただ、各ノードの見た目や調整のしやすさは、まだ詰めている段階。

← 記事一覧へ