ジオメトリノードは、ノードをつなぐだけで、モデルの形を作ったり変えたりする機能です。
この記事では、猿の表面に小さな球を散らす例で、基本を確かめました。
- 使うノードは、「面にポイント配置」→「ポイントにインスタンス作成」→「ジオメトリ統合」。散らす形(ICO球)をつなぐ
- 「密度」を30から150にすると、球は約370個から約1,880個になった
- そのまま「適用」すると、散らした球が消える。先に「インスタンス実体化」をはさむ
- Blender 5.2.1 では、モディファイアーの値は mod[“Socket_1”] では変えられず、mod.properties.inputs で変える
この記事の結果は、2026年9月29日に Blender 5.2.1 LTS を背景実行(画面なし)して試したものです。
ノードや項目の名前は、Blender の日本語の表示に合わせています。
作るもの
猿(スザンヌ)の表面の面ごとに、点をランダムに置き、点の場所に小さな球を並べます。
元の猿の形は残したいので、最後に元のメッシュと球を1つにまとめます。
使うノード
| ノード(日本語表示) | 役目 | つなぐもの |
|---|---|---|
| グループ入力 | モディファイアーに渡された形と、設定値を受け取る | ジオメトリ・密度・半径 |
| 面にポイント配置 | 面の上に点をランダムに置く | メッシュ(入力)、密度 |
| ICO球 | 散らす形を作る | 半径 |
| ポイントにインスタンス作成 | 各点に、ICO球のコピーを置く | ポイント、インスタンス |
| ジオメトリ統合 | 元の猿とコピーを1つにまとめる | 猿とインスタンス |
| グループ出力 | 結果を返す | ジオメトリ |
作り方
- 猿のオブジェクトを選び、「モディファイアー」から「ジオメトリノード」を追加して、「新規」を押す
- ジオメトリノードの画面で、上のノードを追加してつなぐ(追加は Shift+A)
- グループ入力に「密度」と「半径」の入力を足して、それぞれ「面にポイント配置」の「密度」と「ICO球」の「半径」につなぐ
- 密度と半径の値を、モディファイアーの画面で変える
練習用の新規ファイルで初期キューブを削除し、Scriptingワークスペースの新しいテキストへ次の例を貼り、1回だけ実行します。
import bpy
if bpy.data.objects.get("ScatterPractice"):
raise RuntimeError("ScatterPractice が既にあります。練習用の新規ファイルで実行してください。")
bpy.ops.mesh.primitive_monkey_add()
ob = bpy.context.object
ob.name = "ScatterPractice"
ng = bpy.data.node_groups.new("ScatterPractice", "GeometryNodeTree")
ng.interface.new_socket("Geometry", in_out="INPUT", socket_type="NodeSocketGeometry")
ng.interface.new_socket("Geometry", in_out="OUTPUT", socket_type="NodeSocketGeometry")
ng.interface.new_socket("Density", in_out="INPUT", socket_type="NodeSocketFloat").default_value = 30.0
ng.interface.new_socket("Size", in_out="INPUT", socket_type="NodeSocketFloat").default_value = 0.05
n = ng.nodes
gi = n.new("NodeGroupInput")
go = n.new("NodeGroupOutput")
dp = n.new("GeometryNodeDistributePointsOnFaces")
iop = n.new("GeometryNodeInstanceOnPoints")
ico = n.new("GeometryNodeMeshIcoSphere")
ico.inputs["Subdivisions"].default_value = 1
jg = n.new("GeometryNodeJoinGeometry")
links = ng.links
for output, target in [
(gi.outputs["Geometry"], dp.inputs["Mesh"]),
(gi.outputs["Density"], dp.inputs["Density"]),
(gi.outputs["Size"], ico.inputs["Radius"]),
(dp.outputs["Points"], iop.inputs["Points"]),
(ico.outputs["Mesh"], iop.inputs["Instance"]),
(gi.outputs["Geometry"], jg.inputs["Geometry"]),
(iop.outputs["Instances"], jg.inputs["Geometry"]),
(jg.outputs["Geometry"], go.inputs["Geometry"]),
]:
links.new(output, target)
mod = ob.modifiers.new("Scatter", "NODES")
mod.node_group = ng
for node, position in [(gi, (-600, 100)), (dp, (-350, 200)),
(ico, (-350, -150)), (iop, (-100, 200)),
(jg, (150, 100)), (go, (350, 100))]:
node.location = position
ノードの内部の名前(GeometryNodeDistributePointsOnFaces など)は、日本語表示とは別です。
密度と半径を変えて描画した

| 密度 | 半径 | 球の数 | 見た目 |
|---|---|---|---|
| 0 | 0.05 | 0 | 元の猿のまま |
| 30 | 0.05 | 約370個 | まばらに球が並ぶ |
| 150 | 0.05 | 約1,880個 | 表面がつぶつぶになる |
| 150 | 0.12 | 約1,880個 | 大きな球が重なって、表面を覆う |
密度を5倍にすると、球の数も約5倍になりました。
適用すると球が消える
ジオメトリノードのモディファイアーを「適用」して、普通のメッシュにしたくなることがあります。
そのまま適用すると、頂点の数は507のままで、散らした球は消えてしまいました。
「ポイントにインスタンス作成」で置いたものは、メッシュではなく「インスタンス」で、適用しても取り込まれないためです。
「ポイントにインスタンス作成」と「ジオメトリ統合」の間に「インスタンス実体化」をはさむと、球が残り、頂点は23,091(元の507+球1,882個×12頂点)になりました。
| つなぎ方 | 適用した後の頂点数 |
|---|---|
| インスタンス作成 → 統合 | 507(球が消える) |
| インスタンス作成 → インスタンス実体化 → 統合 | 23,091(球が残る) |
実体化すると、球1つずつが本物のメッシュになるので、数が多いと重くなります。
5.2でスクリプトから値を変える
以前の Blender では、モディファイアーの値を mod[“Socket_1”] = 30 のように変えられましたが、5.2.1 ではエラーになりました。
TypeError: bpy_struct[key] = val: id properties not supported for this type5.2.1 では、次のように書くと変えられました。
import bpy
ob = bpy.context.object
if ob is None or ob.type != "MESH":
raise RuntimeError("練習用メッシュを選んでください。")
mod = ob.modifiers.get("Scatter")
if mod is None or mod.type != "NODES" or mod.node_group is None:
raise RuntimeError("上の例で作成した Scatter モディファイアーが必要です。")
socket = next((item for item in mod.node_group.interface.items_tree
if item.item_type == "SOCKET" and item.in_out == "INPUT"
and item.name == "Density"), None)
if socket is None:
raise RuntimeError("Density 入力がありません。")
getattr(mod.properties.inputs, socket.identifier).value = 150.0
ob.update_tag()
Socket_1 のようなidentifierは入力の追加順で変わるため、決め打ちせず Density という名前の入力を探して値を変えます。
ng.interface.items_tree の各項目の identifier で調べられます。
練習用ファイルで適用前後を確かめる
Blender練習用データをダウンロード(ZIP・約2.1MB)
ZIPを別フォルダーへ展開してから開き、元のファイルを上書きせずコピーで試してください。
Blender 5.2.1 LTSで生成し、背景実行でデータと処理を検証したものです。
GUIのクリック操作とUnityへの取り込みは、今回の検証には含みません。
- scatter-density30.blend を開き、ScatterPracticeを選んで密度と半径を確認する
- コピー上で密度を150に変え、球の数とメッシュの重さを比べる
- scatter-realize-ready.blend を別に開く。このファイルはインスタンス実体化を接続済み
- コピー上でモディファイアーを適用し、メッシュの頂点数を確認する
2026年10月2日に Blender 5.2.1 LTSの背景実行で再検証しました。
密度30で370個、150で1,882個になり、実体化後の適用では23,091頂点が残りました。
実体化を通さない例を適用すると、猿の507頂点だけが残ることも再確認しました。
球が見えないときは密度と半径の値、インスタンス作成の入力、グループ出力までの接続を確認します。
ノードを置いただけでは変化しないので、下の練習用ファイルとリンクの接続先を見比べてください。
適用直後ならCtrl+Zで戻し、保存後なら適用前の練習用ファイルを開き直します。
まとめ
- 「面にポイント配置」で点を置き、「ポイントにインスタンス作成」でコピーを置く
- 最後は「ジオメトリ統合」で、元の形とまとめる
- 適用する前に、「インスタンス実体化」を入れる。入れないと球が消える
- 5.2.1 のスクリプトは mod.properties.inputs で値を変える
描画のエンジンの選び方は、CyclesとEEVEEの違いを見てください。
参考:Blender 5.2.1 LTS での実行結果(2026年9月29日)。
