画像から 3D の模型を起こす Pixal3D で、検証用に用意した人物を作り、リアルタイムで動かせる軽さ(12,000 三角形・骨付き)まで整えられるかを技術検証しました。動きを付けるところまではできましたが、見た目は粗いままで、成功とは言いがたい出来でした。
この記事は、その途中の、93 万面の模型を減らす段で、ボクセルで作り直した形が網のように抜けてしまった話です。
結論
- Pixal3D で4方向の絵から起こした人物は、厚さ 5mm ほどの中空の殻でした。頭の前から入った光線は 5.7mm で抜け、次に当たるのは後頭部です。
- 殻がボクセル(14mm)より薄いので、Voxel Remesh で頭・胴・袖が網になりました。直に Decimate すると形が潰れました。穴を埋めても結果は変わりませんでした。
- 面が通る升に印を付けて外の端から塗りつぶし、塗れなかった升を中身にしてから作り直すと、網にならずに 12,000 三角形まで減らせました(整える段全体で 16 秒)。解けたのは網の抜けまでで、升が 14mm だと目・口の彫りや襟の縁が消え、仕上がりはごつごつしていました。
試した環境
- Pixal3D:4方向の絵(T ポーズの正面・横・背面・反対の横)から形と色を一度に起こす使い方、解像度 1024。1体の生成に 179 秒で、出てきた模型は 93 万面
- Blender 4.5 LTS:整える処理を Python のスクリプトにして、
blender -b(画面なし)で動かした - 目標:約 2.6 頭身、40〜60px ほどの小さな表示を想定した人物。12,000 三角形
前に通った手順を当てたら、網になった
Pixal3D の出来は良く、色を抜いて単色で描いても、顔・髪・ポケットまで読み取れました。

これを 12,000 三角形にするのに、前に別の人物で通った「ボクセル 14mm で作り直す → 平滑 → Decimate」をそのまま当てました。すると、頭・胴・袖が網のように抜けました。

ボクセルを通さずに直に Decimate すると、今度は形が潰れました。

試したやり方と結果の関係を図にすると、次のようになります。中を詰めるやり方は、この後で説明します。
穴を疑ったが、穴ではなかった
網になったので、まず模型の穴を疑いました。頂点を 2.3e-5 の距離で繋いだ後に測ると、境界の辺が 229 本、多様体でない辺が 1,920 本で、塊は1つでした。境界の辺がつくる穴は 180 個ありましたが、どれも半径 6.8mm 以下で、ボクセルの 14mm より小さな物です。bmesh.ops.holes_fill で埋めようとしても、1面も埋まりませんでした。
頂点を繋ぐ・面の向きを揃える・穴を埋める、のどれをしても、ボクセルで作り直した後の面積は 8.91 m²、面の数は 96,252 で変わりませんでした。作り直した直後の形は 2,238 個の塊に割れていて、一番大きい塊が 58,958 頂点、残りの塊が合わせて 41,472 頂点です。網目を見ると穴埋めを何通りも試したくなりますが、どの手を打っても面積と面の数が1つも動かなかったので、穴の線は捨てました。
光線を通すと、中空の殻だった
模型の高さを 2.3 に合わせ、Blender の BVHTree.ray_cast で光線を通して、面をくぐる位置を順に数えました。in は外向きの面に入る所、out は抜ける所です。
# [距離, in=外向きの面に入る / out=抜ける]
face_y: [[1.548, "in"], [1.5537, "out"], [2.4979, "in"], [2.5031, "out"]]
chest_y: [[1.8456, "in"], [1.8508, "out"], [2.0815, "in"], [2.0867, "out"], ...]
thigh_y: [[1.8076, "in"], [1.8134, "out"], [2.1233, "in"], [2.129, "out"]]
頭の前から入った光線は 5.7mm で抜け、次に当たるのは後頭部です。その間には何もありません。胸の前は 5.2mm、太ももの前は 5.8mm で抜けました。Pixal3D の人物は、中身の無い、厚さ 5mm ほどの殻でした。
殻の厚さが 5mm ほどなのに対して、ボクセルは 14mm です。殻がボクセルより薄いので、作り直すと頭・胴・袖が網になっていました。

升に印を付けて、外から塗りつぶす
殻のままでは作り直せないので、先に中身を作りました。通った手順は次のとおりです。
- 模型を囲む升(3次元の格子)を用意し、面が通る升に印を付ける
- 格子の外の端から、上下・前後・左右の6近傍で塗りつぶす(印の付いた升は越えない)
- 塗れなかった升を中身とし、その升の外面からメッシュを作る
- Voxel Remesh(7mm)で作り直す
- Shrinkwrap(最寄りの面に吸い付ける方式)で、元の殻の外側の面に吸い付ける
- 平滑をかけ、Decimate で 12,000 三角形にする
升の大きさは、最初は前に別の人物で通った 14mm にしました。整える段全体で 16 秒で、頭・胴・袖の抜けは無くなりました。

ただ、升が 14mm だと目・口の彫りや襟の縁が消えて、仕上がりがごつごつしました。
確かめていないこと
- 髪の長い人物やスカートの人物で、同じ塗りつぶしが通るかは確かめていません。
おわりに
生成した模型は、見た目が整っていても中身が詰まっているとは限りませんでした。ボクセルでの作り直しが網になったら、穴を探す前に、光線で面をくぐる位置を数えると、殻かどうかが分かります。中を詰めて網の抜けは解けましたが、減らした人物の見た目は粗いままでした。
※ Pixal3D と Blender の振る舞いは執筆時点で試した物で、いまは変わっている可能性があります。


