自動生成・配置ルール

密度マスク散布

Density-Masked Scattering

マスクの濃さで草や石の配置密度を変える。

10 / 10

インタラクティブデモ

デモを準備しています…

密度マスク散布

ドラッグで視点を回転、Ctrl(⌘)+ スクロールでズーム。タッチ操作は 2 本指です。

ひとことで

地面の場所ごとに「どれくらい置いてよいか」を 0〜1 の値(密度マスク)で持たせ、その値を置く確率として草・木・岩などを散布する方法です。マスクは、標高・斜面の急さ・ノイズ・手で塗った値などを掛け合わせて作ります。一様にばらまくと水の中にも崖にも草が生えますが、マスクを使えば、低くなだらかな所には草、まとまった所には林、急な斜面には岩、という自然な景色になります。

ゲームでの使いどころ

  • 草・花・小石の散布:広いフィールドに何万本もの草を、地形に合わせて置く(Unreal の Foliage、Unity の Terrain の Detail)。
  • 木・岩の配置:森のまとまり、川沿いの木、崖下の岩など、ルールに沿った配置。
  • 手で塗って調整:デザイナーがブラシで「ここは多め」「ここは道なので消す」と塗り、自動生成の結果を直す。
  • ゲームの要素:敵の出現しやすさ、資源の出やすさ、戦闘が起きやすい場所などにも同じ仕組みが使える。

しくみ

候補の点 xi\mathbf{x}_i に、それぞれ固定の乱数 ri∈[0,1)r_i \in [0, 1) を持たせておき、

ri<ρ(xi)⋅k⇒置くr_i < \rho(\mathbf{x}_i) \cdot k \quad \Rightarrow \quad \text{置く}

とします。ρ\rho が密度マスク、kk は全体の密度です。マスクは複数の条件の掛け算で作ります。

ρ=(1−smoothstep⁡(h0,h1,h))⏟高すぎない⋅(1−smoothstep⁡(s0,s1,s))⏟急すぎない⋅smoothstep⁡(a,b,n)⏟ノイズのむら+手で塗った値\rho = \underbrace{\big(1 - \operatorname{smoothstep}(h_0, h_1, h)\big)}_{\text{高すぎない}} \cdot \underbrace{\big(1 - \operatorname{smoothstep}(s_0, s_1, s)\big)}_{\text{急すぎない}} \cdot \underbrace{\operatorname{smoothstep}(a, b, n)}_{\text{ノイズのむら}} + \text{手で塗った値}

掛け算にするのは、「どれか 1 つでも条件を満たさなければ置かない」ためです。hh は標高、ss は斜面の急さ(高さの勾配の大きさ)、nn はノイズです。

固定の乱数を使う理由:毎回新しい乱数で判定すると、マスクを少し変えただけで全部の草が入れ替わり、ちらつきます。候補ごとに乱数を固定しておけば、マスクを塗り足した所だけ草が増え、ほかはそのまま残ります。

実装のポイント

  • 候補の並び:候補を完全なランダムにすると、偶然の固まりやすき間ができます。ポアソンディスク分布やジッター付きの格子にしておくと、密度が低くても間隔の自然な配置になります。
  • 層ごとにマスクを分ける:草・木・岩で別々のマスクを使い、「木の下には草を減らす」のように層どうしで影響し合わせると、よりそれらしくなります。
  • 大量に描く:草のような数万個の物は、GPU インスタンシングで 1 回の描画命令にまとめます。遠くは密度を下げたり、置かなかったりします。
  • チャンクごとに作る:広い世界では、カメラの近くのチャンクだけ候補を生成・判定し、遠ざかったら捨てます。乱数の種をチャンクの座標から決めれば、戻ってきても同じ配置になります。

つまずきやすい点

  • 境目がくっきりしすぎる:条件をしきい値で 0/1 に切ると、草の生える所と生えない所の境目が不自然な直線になります。smoothstep でなだらかに変化させます。
  • マスクと見た目のずれ:地面のテクスチャ(草の色)と散布のマスクが別々だと、茶色い地面に草が生えたりします。同じマスクから両方を作ります。
  • 密度と負荷:密度をそのまま上げると、描画の負荷が急に増えます。距離による間引きや LOD と一緒に設計します。

デモで試すこと

  1. 草は低くなだらかな所に、木はノイズのまとまりに沿った林に、岩は急な斜面に集まっていることを確かめてください。
  2. 「一様にばらまく」に切り替えると、水の中や山頂にも同じように生え、不自然な景色になります。
  3. 「標高」「斜面」「ノイズ」の条件を 1 つずつ切って、それぞれの条件が景色にどう効いているかを見比べてください。「草のマスクを地面に表示」で、マスクの値が見えます。
  4. 地面をドラッグすると、塗った所だけ草が増えます。「草を消す」にしてドラッグすると、道を作れます。ほかの草が入れ替わらないことも確かめてください。

参考資料

WaveFunctionCollapse ↗

分野全体の資料で、この項目を直接扱っているとは限りません。