第1回 Minecraft × PLY点群:3DGS PLY形式の応用を探る
📌 3D Gaussian Splatting(3DGS)と PLY形式
3D Gaussian Splatting とは
3D Gaussian Splatting(3DGS)は、NeRF(Neural Radiance Fields)系の最新3D再構成手法で、点群にガウス分布を持たせて高速レンダリングを行います。
従来のNeRFに比べ、圧倒的に高速でリアルタイム描画が可能です。
原理としては、シーンを 「色付きの半透明なガウス点」 で構成し、それらをGPU上で効率的に描画します。
出力形式としての PLY
3DGSの出力フォーマットとしてよく使われるのが PLY(Polygon File Format) です。
PLYはもともとスタンフォード大学で3Dスキャンデータを扱うために開発されたシンプルな形式で、点群やポリゴンメッシュを格納できます。
各点(頂点)には以下のような属性を付与できます。
- 位置座標(x, y, z)
- 色(r, g, b)
- 法線ベクトル
- 半径やスケール
- 不透明度 など
PLYファイルの構造
PLYは ヘッダー部 と データ部 に分かれます。
-
ヘッダー部
- データ形式(
ascii
またはbinary
) - 頂点数、面数
- 各属性の型と名称
- データ形式(
-
データ部
- 頂点ごとに属性値を列挙(ASCII形式では1行ごと)
例(簡易的なASCII形式の点群)
ply
format ascii 1.0
element vertex 3
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
end_header
0.0 0.0 0.0 255 0 0
1.0 0.0 0.0 0 255 0
0.0 1.0 0.0 0 0 255
NeRF由来のPLYと3DGS由来のPLYの違い
同じ「PLY形式」でも、中に含まれる属性は異なります。
-
NeRF由来のPLY
- 位置(x, y, z)
- 色(r, g, b)程度の最小限の属性
-
3DGS由来のPLY
- 上記に加えてガウス分布のスケール・回転・不透明度など、レンダリングに必要な追加属性を多数保持
注意点
この仕様の違いにより、同じPLY拡張子でもビューアや処理スクリプトによっては
- 属性を正しく読み取れない
- 追加情報が無視される
といった表示や解析の不一致が発生することがあります。
🛠 3DGSでモデル作成:Postshotの利用
今回は、Postshot というGUIツールを使って、写真から3DGSモデルを作成しました。
参考: Postshotの使い方
手順概要
-
画像または動画を用意
→ 今回はNeRF公式のLEGOデータを利用
GitHub: bmild/nerf(Data) -
Postshotにインポート
→ カメラパラメータ推定と3DGS変換を自動で実行 -
PLY形式でエクスポート
→ このPLYは「位置+色+半径」情報を含む点群データ
🎮 MinecraftでのPLY応用アイデア
PLY形式の3Dデータは、点群(point cloud)の集合です。
「この点群をブロックとして置き換えれば、Minecraft内で再構成できるのでは?」という発想から、今回はそのアイデアをちょっと試してみます。
3DGSモデルは本来、ガウス分布を持った点群ですが、Pythonスクリプトを使えばMinecraftのブロック配置データに変換可能です。
座標と色情報をもとに、近い色のブロックを選んで配置することで、現実や3Dスキャンの結果をMinecraft内に再現できます。
応用例
-
3DGSモデル → Minecraftブロック化
点の位置と色から、最も近い色のブロックを選び、ワールドに配置 -
NeRFモデルのバーチャル展示
フォトリアルな建物やオブジェクトをMinecraft上で再構築 -
教育・研究用途
フォトグラメトリやNeRF技術の成果を、Minecraftの中で直感的に可視化
🎮 PLY点群をMinecraftにブロック化する(3DGS対応)
📝 背景
3D Gaussian Splatting(3DGS)は通常、PLYに色情報を含めません。
そのため今回は色再現ではなく、すべて白い羊毛(WOOL)でブロック化する形で実装します。
実装の発想や流れは、以前作成した記事「PythonでMinecraftに静止画と動画を描画してみた」を参考にしています。
💻 コード全文
from plyfile import PlyData
from mcpi.minecraft import Minecraft
from mcpi import block
def build_pointcloud_scaled_thinned(ply_path, scale=50, thinning=2):
# ① PLY読み込み
plydata = PlyData.read(ply_path)
vertices = plydata['vertex']
# ② Minecraft接続
mc = Minecraft.create("127.0.0.1")
start_pos = mc.player.getTilePos()
# ③ 座標範囲の取得
xs = [v['x'] for v in vertices]
ys = [v['y'] for v in vertices]
zs = [v['z'] for v in vertices]
min_x, max_y, min_z = min(xs), max(ys), min(zs)
max_x, min_y, max_z = max(xs), min(ys), max(zs)
placed = set()
WOOL = block.WOOL.id
# ④ 頂点ごとに処理
for i, v in enumerate(vertices):
# ⑤ 間引き
if i % thinning != 0:
continue
# ⑥ スケーリングと座標変換
x = int(round((v['x'] - min_x) * scale))
y = int(round((max_y - v['y']) * scale)) # y軸反転
z = int(round((v['z'] - min_z) * scale))
coord = (start_pos.x + x, start_pos.y + y, start_pos.z + z)
# ⑦ 重複防止
if coord in placed:
continue
placed.add(coord)
# ⑧ ブロック設置(白羊毛)
mc.setBlock(*coord, WOOL, 0)
if __name__ == "__main__":
# ⑨ 実行
build_pointcloud_scaled_thinned("my_world_radius50.ply", scale=50, thinning=2)
📖 コード解説
-
PLY読み込み
PlyData.read()
でPLYを読み込み、vertex
要素から全頂点データを取得。 -
Minecraft接続
Minecraft.create()
でサーバーに接続し、プレイヤーの位置を基準座標として取得。 -
座標範囲の取得
x, y, z の最小値・最大値を求め、後のスケーリングや座標反転に使用。 -
頂点ごとに処理
点群の各頂点を順番に処理。 -
間引き
thinning
間隔で点を利用。点群の量が1万と多いので、点群密度が高い場合の負荷軽減に有効。 -
スケーリングと座標変換
- PLYは通常、座標を (1.4534..., 2.0987..., 3.4839...) といった実数(x,y,z)で保存しています。
- しかしMinecraftはブロック単位(1ブロック = 1整数座標)で構築されるため、そのままだと非常に小さく見えてしまいます。
- そこで、PLY座標から最小値を引いて0基準に変換した後、
scale
倍(例: 100倍)することで、Minecraftの世界で人間サイズに近い大きさに再現します。 - y軸はPLYとMinecraftで方向が逆のため、上下反転を行います。
-
重複防止
配置済みの座標はset
に記録し、再設置を回避。 -
ブロック設置(白羊毛)
mc.setBlock()
でブロックを設置。
3DGSのPLYには色情報がないため、今回は白羊毛で統一。 -
実行
ファイル名・スケール・間引き率を指定して関数を実行。
では、その「結果」の部分もZenn記事風に整理して、文章と見出しを整えつつ、画像を挿入する形にまとめてみます。
🏁 結果
元のPLYモデル(3DGS出力)は、色情報が含まれていないため、Minecraft内では白い羊毛で再現しました。
元画像
Minecraft上で再現した結果
色は反映されていませんが、点群構造をMinecraftブロックで再現できることは確認できました。
さらに、PLYに色情報があれば色付きブロックや建物の再現も可能です。
今回の結果から、PLYデータをMinecraftに応用できる道を見つけられたと言えますね。
🔮 まとめと展望
- 3DGSはNeRFの高速化版として注目される技術
- PostshotでPLY形式にエクスポート可能
- Pythonを使えばMinecraftなど別環境での再利用が容易
- 教育・アート・ゲームなど幅広く応用可能
次回は、この方式の確認を詳しくみていようと思います。
Discussion