This explanation is currently available in Japanese.
ひとことで
地面の場所ごとに「どれくらい置いてよいか」を 0〜1 の値(密度マスク)で持たせ、その値を置く確率として草・木・岩などを散布する方法です。マスクは、標高・斜面の急さ・ノイズ・手で塗った値などを掛け合わせて作ります。一様にばらまくと水の中にも崖にも草が生えますが、マスクを使えば、低くなだらかな所には草、まとまった所には林、急な斜面には岩、という自然な景色になります。
ゲームでの使いどころ
- 草・花・小石の散布:広いフィールドに何万本もの草を、地形に合わせて置く(Unreal の Foliage、Unity の Terrain の Detail)。
- 木・岩の配置:森のまとまり、川沿いの木、崖下の岩など、ルールに沿った配置。
- 手で塗って調整:デザイナーがブラシで「ここは多め」「ここは道なので消す」と塗り、自動生成の結果を直す。
- ゲームの要素:敵の出現しやすさ、資源の出やすさ、戦闘が起きやすい場所などにも同じ仕組みが使える。
しくみ
候補の点 に、それぞれ固定の乱数 を持たせておき、
とします。 が密度マスク、 は全体の密度です。マスクは複数の条件の掛け算で作ります。
掛け算にするのは、「どれか 1 つでも条件を満たさなければ置かない」ためです。 は標高、 は斜面の急さ(高さの勾配の大きさ)、 はノイズです。
固定の乱数を使う理由:毎回新しい乱数で判定すると、マスクを少し変えただけで全部の草が入れ替わり、ちらつきます。候補ごとに乱数を固定しておけば、マスクを塗り足した所だけ草が増え、ほかはそのまま残ります。
実装のポイント
- 候補の並び:候補を完全なランダムにすると、偶然の固まりやすき間ができます。ポアソンディスク分布やジッター付きの格子にしておくと、密度が低くても間隔の自然な配置になります。
- 層ごとにマスクを分ける:草・木・岩で別々のマスクを使い、「木の下には草を減らす」のように層どうしで影響し合わせると、よりそれらしくなります。
- 大量に描く:草のような数万個の物は、GPU インスタンシングで 1 回の描画命令にまとめます。遠くは密度を下げたり、置かなかったりします。
- チャンクごとに作る:広い世界では、カメラの近くのチャンクだけ候補を生成・判定し、遠ざかったら捨てます。乱数の種をチャンクの座標から決めれば、戻ってきても同じ配置になります。
つまずきやすい点
- 境目がくっきりしすぎる:条件をしきい値で 0/1 に切ると、草の生える所と生えない所の境目が不自然な直線になります。smoothstep でなだらかに変化させます。
- マスクと見た目のずれ:地面のテクスチャ(草の色)と散布のマスクが別々だと、茶色い地面に草が生えたりします。同じマスクから両方を作ります。
- 密度と負荷:密度をそのまま上げると、描画の負荷が急に増えます。距離による間引きや LOD と一緒に設計します。
デモで試すこと
- 草は低くなだらかな所に、木はノイズのまとまりに沿った林に、岩は急な斜面に集まっていることを確かめてください。
- 「一様にばらまく」に切り替えると、水の中や山頂にも同じように生え、不自然な景色になります。
- 「標高」「斜面」「ノイズ」の条件を 1 つずつ切って、それぞれの条件が景色にどう効いているかを見比べてください。「草のマスクを地面に表示」で、マスクの値が見えます。
- 地面をドラッグすると、塗った所だけ草が増えます。「草を消す」にしてドラッグすると、道を作れます。ほかの草が入れ替わらないことも確かめてください。