画像から 3D の模型を起こす Pixal3D で作り、Blender で骨と Mixamo の動きを付けた、検証用に用意した人物を、Unity 6 に取り込んで動かせるかを技術検証しました。12,000 三角形・骨付きの人物に動きを付けるところまではできましたが、見た目は粗いままで、成功とは言いがたい出来でした。

この記事は、その途中で、Unity で撮って確かめる所で詰まった話です。Unity を -batchmode で起こして各クリップのコマを撮ったところ、色が付かない・どのコマも同じ姿勢・輪郭がギザギザ、の3つが出ました。

結論

  • Blender の FBX に色の絵を埋めても、Unity 6 では材質に結び付きませんでした。PNG を FBX の隣に置き、ファイル名だけで指す(書き出しで path_mode="STRIP")と付きました。
  • batchmode で SampleAnimation してから撮ると、骨で曲げた形が1フレームに1度しか作られず、どのコマも同じ姿勢に撮れました。BakeMesh した形を別の物体に載せて撮りました。
  • new RenderTexture(256, 256, 24) の既定はアンチエイリアス無し(antiAliasing = 1)で、輪郭と法線マップの細かい凹凸がギザギザに出ました。512 にして antiAliasing = 8 を付けるとなめらかになりました。
  • 確かめの絵を Unity 標準の材質と、平行光1つ・環境光 0.6 で撮ると、髪や上着の色が褪せ、形の凹凸も強く出ました。検証用の Unity プロジェクトに表示を想定した材質を用意して撮ると、色は Blender の絵どおりになり、凹凸もかなり目立たなくなりました。
  • 直せたのは、色の絵の渡し方・コマの撮り方・撮る大きさとアンチエイリアス・確かめに使う材質までで、撮れた人物そのものの見た目は粗いままでした。

試した環境

  • Mac、Unity 6000.4.10f1、ビルトインの描き方、Standard の材質
  • 検証用の Unity プロジェクト。取り込みの設定は Legacy、縮尺 1、ループ
  • 人物:約 12,000 三角形、骨 25 本、色の絵 1024(後から法線マップ 1024 も足した)、待機・応援・歩きの3クリップ
  • 撮る光:平行光1つと環境光 0.6

色の絵が、材質に付かない

Blender から書き出した FBX に色の絵を埋め込んで取り込むと、人物に色が付きませんでした。絵の名前に .png を付けても同じでした。

FBX に色の絵を埋めて取り込んだ人物。色が付いていない

PNG を FBX の隣に置き、FBX からはファイル名だけで指すようにすると、材質に結び付きました。Blender の FBX の書き出しでは、path_mode="STRIP" にします。

bpy.ops.export_scene.fbx(filepath=out_path, path_mode="STRIP")

どのコマも同じ姿勢に撮れる

各クリップのコマを撮るのに、SampleAnimation で姿勢を決めてから、カメラで RenderTexture に描きました。batchmode では、骨で曲げた形が1フレームに1度しか作られず、どのコマも同じ姿勢に撮れました。

SampleAnimation だけで撮った各コマ。どれも同じ姿勢

SkinnedMeshRenderer.BakeMesh で、その時点の曲げた形をメッシュに焼き、別の物体に載せて撮るようにしました。

clip.SampleAnimation(character, time);
skinned.BakeMesh(bakedMesh);          // その時点の姿勢の形を焼く
bakedFilter.sharedMesh = bakedMesh;   // 別の物体に載せて撮る

これで、コマごとに違う姿勢が撮れました。

BakeMesh した形を撮った応援の各コマ。姿勢がコマごとに違う

撮った絵がギザギザ

法線マップを足した人物を撮ると、歩かせた絵がガビガビに見えました。最初はつや(Standard の _Glossiness)を疑いましたが、取り込んだ材質は最初から 0.00 で、0 にしても絵は同じでした。法線マップを外すと、髪の房と上着のしわが消えてのっぺりしたので、法線マップは残しました。

輪郭がギザギザの切り絵と、なめらかな切り絵

原因は撮り方でした。new RenderTexture(256, 256, 24) の既定は antiAliasing = 1、つまりアンチエイリアス無しです。輪郭と、法線マップで足した細かい凹凸がギザギザに出ていました。512 にしてアンチエイリアスを入れると、なめらかに出ました。

var rt = new RenderTexture(512, 512, 24) { antiAliasing = 8 };

撮り方を変えて並べた4枚。前の撮り方、512・アンチエイリアス 8、つや 0、法線マップ無し

左から、前の撮り方(256・アンチエイリアス無し)、512・アンチエイリアス 8、つやを 0 にした物、法線マップを外した物です。

模型が荒れているのか、撮り方で荒れて見えるのかを見分けるため、確かめの絵は想定した表示より細かく、アンチエイリアスを入れて撮ることにしました。

確かめの絵は、表示を想定した材質で撮る

ギザギザを直した後も、人物は凹凸が強く、変に見えました。確かめの絵を、Unity 標準の材質と、平行光1つ・環境光 0.6 で撮っていたためです。この条件では、髪が褪せた紫に、上着が薄い桃色になり、形の凹凸も強く出ていました。

表示を想定した材質は、決まった向きの光で、明るさを 70〜100% の間でしか変えず、法線マップは使いません。検証用のプロジェクトにこの材質を用意して同じ人物を撮ると、色は Blender の絵どおりになり、凹凸もかなり目立たなくなりました。

同じ人物を Unity 標準の材質(左の2列)と、表示を想定した材質(右の2列)で撮った並び。右は色が絵どおりで、凹凸が目立たない

左の2列が Unity 標準の材質、右の2列が表示を想定した材質で撮った物です。この材質は法線マップを使わないので、法線マップで足した細部はここでは効きません。その細部を陰として色に焼いて戻した話は、別の記事にまとめました。

おわりに

撮った絵がおかしいときは、模型を直す前に、渡し方と撮り方を疑う値打ちがありました。特にアンチエイリアス無しの撮り方は、模型の荒れと見分けが付きませんでした。ただ、直せたのは渡し方と撮り方までで、撮れた人物そのものの見た目は粗いままでした。

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