画像から 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 の出来は良く、色を抜いて単色で描いても、顔・髪・ポケットまで読み取れました。

Pixal3D が起こした 93 万面の人物を単色で描いた物。顔・髪・ポケットまで読める

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

ボクセル 14mm で作り直した人物。頭・胴・袖が網のように抜けている

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

直に Decimate した人物。形が潰れている

試したやり方と結果の関係を図にすると、次のようになります。中を詰めるやり方は、この後で説明します。

中空の殻に3つのやり方を当てた結果

穴を疑ったが、穴ではなかった

網になったので、まず模型の穴を疑いました。頂点を 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 ほどの殻でした。

顔の前の殻は 5.7mm、胸の前は 5.2mm、太ももの前は 5.8mm で、ボクセルの 14mm より薄い

殻の厚さが 5mm ほどなのに対して、ボクセルは 14mm です。殻がボクセルより薄いので、作り直すと頭・胴・袖が網になっていました。

殻だけの人形に積み木を詰めて中身を作る様子

升に印を付けて、外から塗りつぶす

殻のままでは作り直せないので、先に中身を作りました。通った手順は次のとおりです。

  1. 模型を囲む升(3次元の格子)を用意し、面が通る升に印を付ける
  2. 格子の外の端から、上下・前後・左右の6近傍で塗りつぶす(印の付いた升は越えない)
  3. 塗れなかった升を中身とし、その升の外面からメッシュを作る
  4. Voxel Remesh(7mm)で作り直す
  5. Shrinkwrap(最寄りの面に吸い付ける方式)で、元の殻の外側の面に吸い付ける
  6. 平滑をかけ、Decimate で 12,000 三角形にする

升の大きさは、最初は前に別の人物で通った 14mm にしました。整える段全体で 16 秒で、頭・胴・袖の抜けは無くなりました。

中を塗りつぶしてから 12,000 三角形に減らした人物。抜けは無い

ただ、升が 14mm だと目・口の彫りや襟の縁が消えて、仕上がりがごつごつしました。

確かめていないこと

  • 髪の長い人物やスカートの人物で、同じ塗りつぶしが通るかは確かめていません。

おわりに

生成した模型は、見た目が整っていても中身が詰まっているとは限りませんでした。ボクセルでの作り直しが網になったら、穴を探す前に、光線で面をくぐる位置を数えると、殻かどうかが分かります。中を詰めて網の抜けは解けましたが、減らした人物の見た目は粗いままでした。

※ Pixal3D と Blender の振る舞いは執筆時点で試した物で、いまは変わっている可能性があります。