ビルを1棟ずつ手で並べていたら、街なんて一生完成しません。でも BlenderのGeometry Nodes(ジオメトリノード) を使えば、ノードをいくつか繋ぐだけで、見渡す限りのビル群が一瞬で生成できます。今回はそのプロシージャルな街づくりに挑戦し、最後は同じ街を「ローポリの昼」から「光あふれる夜景」へ一瞬で変身させてみました。
うまくいった所だけでなく、窓の表現で一度失敗した話や夜景の明るさ調整で何度もやり直した話まで、正直に記録しています。
地面のグリッドにビルを自動で敷き詰め、高さをランダムにし、道路や空き地を作り、窓を光らせる——その「考え方(どのノードが何をしているか)」を1つずつ追いかけます。最後の見せ場は、街を作り直さずに見た目だけ差し替えるテクニックです。
Geometry Nodesとは(プロシージャル生成のおさらい)
Geometry Nodesは、Blenderに搭載された「計算で形を作る」仕組みです(公式マニュアル)。マウスで頂点を動かす代わりに、「点を並べる」「その点に箱を置く」「高さをランダムにする」といった処理(ノード)を線で繋いで形を組み立てます。
- プロシージャル(手続き的):手作業ではなく、ルールに従って自動で形を作る
- 非破壊:元の形は壊さず、ノードの数値を変えるだけで結果が変わる
- インスタンス:同じ箱を「実体コピー」ではなく「分身」として大量配置するので軽い
この「ルールで街を生やす」発想こそ、ビル数千棟でもPCが固まらない理由です。
今回の検証環境
すべて Mac 1台(MacBook Pro M4)で制作・レンダリングしました。再現の参考にしてください。
| 項目 | 内容 |
|---|---|
| Blender | 5.1.1 |
| マシン | MacBook Pro(Apple Silicon M4) |
| 作業用レンダラー | EEVEE Next(軽い・リアルタイム) |
| 仕上げ用レンダラー | Cycles(リアル・夜景用) |
| 出力解像度 | 1280 × 720 |
| 街の規模 | 40 × 40 のグリッド(最大約1600区画) |
街づくりの全体像(ノード構成)
まず完成形のノード構成を見てください。一見ごちゃごちゃしていますが、流れは「① 点を並べる → ② いらない点を消す → ③ 残った点に箱を置く」のたった3ステップです。
太い流れ(上の段)が「地面 → 点 → 削除 → ビル配置 → 出力」の本筋です。下にぶら下がっている小さなノード群は、「どの点を道路にするか」「ビルの高さをいくつにするか」を計算している補助パーツです。1つずつ見ていきましょう。
地面のグリッドにビルを敷き詰める
街の骨格は Grid(グリッド)ノードです。これで地面に格子状の点を並べます。今回は 40m × 40m を 41 × 41 の頂点に分割し、1mごとに区画を作りました。
- Grid:格子状のメッシュを作る(Size X/Y = 40、Vertices X/Y = 41)
- Mesh to Points(メッシュ→点群):格子の各頂点を「点」に変換する
- Instance on Points(点群にインスタンス):その点1つ1つに「ビル」を1棟ずつ置く
ビル本体は Cube(立方体)ノードです。そのままだと中心が原点になり地面に半分めり込むので、Transformノードで上に0.5だけ持ち上げ、箱の底面を地面(z=0)に合わせるのがコツです。こうしておくと、後で高さを変えても必ず地面から生えてくれます。
1600棟のビルを実体コピーすると重くなりますが、Instance on Pointsは同じ箱の「分身」を配置するだけなので、データはほぼ1棟分。ビューポートもサクサク動きます。
ビルの高さをランダムにする
全部同じ高さでは「街」になりません。各ビルの高さを 1〜6mの範囲でバラバラにします。ここで使うのが 点ごとの番号(Index) です。
番号をタネにした簡単な計算(サイン関数と小数部分を取る、いわゆる擬似乱数)で、0〜1のランダムな値を作り、それを高さに変換しています。考え方はこうです。
乱数 = 小数部分( sin(点の番号 × 12.9898) × 43758.5453 ) … 0〜1のバラバラな値
ビルの高さ = 1 + 乱数 × 5 … 1〜6mこの高さを Combine XYZ で「幅0.8 × 奥行0.8 × 高さ(ランダム)」のベクトルにまとめ、Instance on Pointsの Scale(拡大率) に差し込みます。これだけで、てんでバラバラな高さのビル街が出来上がります。
道路と空き地をつくる(点の間引き)
ビルがびっしりだと「迷路」になってしまいます。そこで 一部の点を消して、道路と空き地を作ります。使うのは Delete Geometry(ジオメトリ削除) ノードです。
- 道路:点の「行・列」を番号から計算し、6区画ごとの行・列を丸ごと削除。これで碁盤の目の通りができる
- 空き地:先ほどの擬似乱数で 約1割の点をランダムに削除。所々にビルが無い区画ができ、街にリズムが生まれる
「道路の条件」と「空き地の条件」を Maximum(どちらか成立で消す) でまとめ、Delete Geometryの Selection に渡すだけ。たったこれだけで、無機質な格子が「人の住む街」っぽくなります。
窓のemissionマテリアル(一度失敗しました)
ビルの顔は「窓」です。窓を表現するため、マテリアル(材質)側でプロシージャルな窓模様+光る窓(emission)を作ります。
最初は「レンガ(Brick)テクスチャ」で窓を作ろうとしました。ところがインスタンスに貼ると模様がうまく出ず、夜景にしたらビル全体がベタッと光る残念な結果に。原因は、全インスタンスが同じテクスチャ座標を共有してしまい、窓の格子が潰れてしまったことでした。
そこで方針転換し、「ワールド座標(その点が空間のどこにあるか)」から窓の格子を計算する方式にしました。考え方はシンプルです。
縦の格子(フロア) = 高さzを0.35mごとに区切る
横の格子(柱) = (x+y)を0.22mごとに区切る
窓のマス = 縦の格子 AND 横の格子(枠の内側だけ光る)
点灯のばらつき = ノイズで「点いている窓/消えている窓」をランダムにこれなら、ビルの位置に応じて窓が世界の中で正しくタイル状に並び、1つ1つの窓が独立します。点灯のオン・オフをノイズで散らすことで、「全部の部屋に人がいるわけじゃない」リアルな夜景に近づきます。窓の色は暖色(電球色)にしました。
パラメータを変えると街が激変する
プロシージャルの醍醐味は、数値を1つ変えるだけで街がガラッと変わること。同じノード構成のまま、ビルの高さ・太さ・道路の間隔を変えて出力した2パターンです。
▲ 高さを上げ、footprintを細く、道路を広めに → 摩天楼が林立する大都市
▲ 高さを下げ、footprintを太く、道路を多めに → 低層が密集する下町
モデルを作り直したわけではありません。スライダー(数値)を動かしただけで、摩天楼の都市にも、低層の下町にもなる。これがノードで街を組む最大の強みです。
【山場】同じ街のまま、ローポリ→夜景リアルに化けさせる
ここが今回いちばんの見せ場です。Geometry Nodesは「形を作る部分」と「見た目(マテリアル・ライト・レンダラー)」がきれいに分離しています。だから街そのものは一切作り直さず、見た目の設定だけ差し替えて、昼のローポリから夜景リアルへ一瞬で変身できます。
まずは作業中の姿、EEVEEのローポリ(昼)。グレーの箱が並ぶシンプルな状態です。
このまったく同じ街に対して、次の手順を踏むだけで——
- レンダラーをEEVEE → Cyclesに切り替える(同じシーンのまま)
- 窓マテリアルのemissionを強める(昼はほぼ0、夜は強く光らせる)
- ワールド(空)を暗い夜空にする
- 太陽の光をほぼ消す(窓明かりが主役になる)
- Cyclesのサンプル数を上げ、デノイズをかける(夜景のノイズ対策)
- 形はそのまま。箱は1つも作り直さない
結果がこちらです。グレーの箱の群れが、窓明かりがきらめく夜の摩天楼に化けました。
emissionの強さは一発では決まりませんでした。強すぎ(街全体が白飛び)→ 弱すぎ(真っ暗で窓が見えない)→ ちょうど良い、と3回レンダリングして詰めました。夜景は光源(窓)が無数にあるぶんノイズも出やすく、サンプル数アップ+デノイズは必須。露出(Exposure)も少し下げて、白飛びを抑えています。
気をつけたい注意点
- EEVEEとCyclesで見え方が変わる:emissionや反射の出方が違うので、最終確認は必ずCyclesで
- 白飛びに注意:emissionが強すぎると窓が真っ白に潰れる。強度と露出のバランスを取る
- 夜景は重い&ノイジー:解像度とサンプル数は常識的な範囲に抑える(今回は1280×720・サンプル160)
- マテリアルはエンジン両対応のノードで:一部のノードはレンダラー依存なので、EEVEE/Cyclesどちらでも破綻しない組み方にする
p901(手作業GN)・p908(Python API)との違い
「形を自動で作る」手段は他にもあります。これまで試した2つと比べてみます。
| 手法 | 特徴 | 向いている場面 |
|---|---|---|
| Geometry Nodes(今回) | ノードを繋いで非破壊で生成。数値を動かすと即座に反映 | パラメータで結果を探りながら作りたい |
| 手作業モデリング | 1棟ずつ手で作る。自由度は最高だが時間がかかる | 少数の作り込んだ建物 |
| Python(bpy)スクリプト | コードで一括生成。複雑な条件分岐や外部データ連携が得意 | 大量・自動化・データ駆動 |
Geometry Nodesは「コードを書かずに、スライダー感覚でルールを作れる」のが魅力。一方で「外部のCSVから建物データを読む」ような処理はPythonの方が得意です。同じ「自動生成」でも適材適所だと改めて感じました。
まとめ
- ✅ Blender 5.1.1 の Geometry Nodes で、グリッド→点→削除→ビル配置の3ステップで広大な街を自動生成
- ✅ 高さ・道路・空き地を擬似乱数と番号計算でコントロールし、リアルな街並みに
- ✅ 窓のemissionはワールド座標から格子を計算する方式で実装(Brick方式は失敗→方針転換)
- ✅ 【山場】街を作り直さず、レンダラー・マテリアル・ライトだけ差し替えてローポリ昼→夜景リアルへ変身
- ⚠️ ハマり:窓表現の失敗、夜景の明るさを3回やり直し(白飛び⇄暗すぎ)
「形」と「見た目」が分離しているおかげで、1つの街がローポリにも夜景にもなる——この柔軟さこそGeometry Nodesの真骨頂でした。次は、生成した街にカメラを走らせるアニメーションや、もっと建物の形にバリエーションを付けることにも挑戦してみたいです。
それでは、今回はここまで。ありがとうございました😊