mmd-for-unity-proj/mmd-for-unity — pull request #6 by eral (2013-08-26 21:22:00+00:00)
Title: 65536頂点を超えるモデルの対応

概要
====
Unity3Dでは1メッシュで扱える頂点数は16bit(65536)迄で有り、それ以上のPMXモデルは召喚出来ませんでした。
このPullRequestではそれを超えるPMXデータの召喚を可能にします。

手法
====
PMXモデル1体に対して、Unity3D Meshを複数割り当てます。
1メッシュで扱える頂点数が約6万5千ですので、2つ割り当てれば約13万頂点扱えます。
メッシュは(ほぼ)無限に扱えますので、頂点数も同様に(ほぼ)無限に扱う事が可能と成ります。

メッシュの分割はサブメッシュ(≒マテリアル)単位にて行い、順不同で詰められるだけ敷き詰めます。
MMDに於いて描画順は材質登録順ですので順番は重要ですが、
Unity3Dに於いて描画順はサブメッシュ単位で最適化される"筈"です。
依って、順番を守らなくても問題無いだろうと考えています。
また同様に、属するメッシュがばらばらでも問題は無いだろうと考えています。

制限・問題と解決策
====
サブメッシュの頂点数は16bit(65536)迄
----
メッシュの分割はサブメッシュ単位で行いますので、
サブメッシュ1つで16bit(65536)頂点を超える場合は引き続き召喚出来ません。
(今の所、その様なデータは発見出来ていません。)

サブメッシュ単位を割り込む様な分割はデータ上作成出来ますが、
描画結果が相違するだろうと思います。
例えばエッジ付き両面描画透過シェーダの場合、描画は下記の流れになります。

1. 裏面描画
2. 表面描画
3. エッジ描画

このサブメッシュが分離された場合、同じ描画結果を得るには下記の様にしないといけません。

1. サブメッシュ1の裏面描画
2. サブメッシュ2の裏面描画
3. サブメッシュ1の表面描画
4. サブメッシュ2の表面描画
5. サブメッシュ1のエッジ描画
6. サブメッシュ2のエッジ描画

ですが、裏面描画→表面描画→エッジ描画の流れはシェーダー由来ですので、
間にメッシュ切り替えを挟む事が出来ず下記の様に為るだろうと思います。

1. サブメッシュ1の裏面描画
2. サブメッシュ1の表面描画
3. サブメッシュ1のエッジ描画
4. サブメッシュ2の裏面描画
5. サブメッシュ2の表面描画
6. サブメッシュ2のエッジ描画

これではZバッファの更新と相まって、色々ポリゴンが欠けるかと思います。

"シェーダーを更に分割すればもしや"とも思わなくはないですが、
それ以前に多分サブメッシュ1つで16bit(65536)頂点を超えるモデルがそうそう出てこないでしょう。

メッシュアセットが複数に為る
----
今迄は変換すればPrefab,Mesh,Materialディレクトリ,Physicsディレクトリの計4つが作成されていましたが、
今回の変更に依りMeshが複数生成される可能性が出てきました。
依って今回からはMeshesディレクトリを作成し、その中にメッシュを保存しています(例え1つだったとしても)。

旧

miku.pmx
miku.prefab
miku.asset [Mesh]
Materials/
Physics/

新

miku.pmx
miku.prefab
Meshes/
+ 0_miku.asset [Mesh]
+ 1_miku.asset [Mesh]
Materials/
Physics/

多分メッシュが5～6も分割される様なモデルは無いと思いますで、従来通りにpmxと同階層でも良いかもしれません。
そちらの方が良ければ、そう出来ますのでお知らせ下さい。

SkinnedMeshRendererが複数に為る
----
複数のメッシュを表示するには同数のSkinnedMeshRendererが必要に為ります。
GameObject1つに対して複数のSkinnedMeshRendererは付加出来ませんでしたので、GameObjectも同数必要に為ります。
依ってMeshノードを作成し、その下にSkinnedMeshRendererの付加したGameObjectをぶら下げる形にしています。

旧

miku [MMDEngine] [SkinnedMeshRenderer] [Animation]
+ Expression
+ Model
+ Physics

新

miku [MMDEngine] [Animation]
+ Expression
+ Mesh
| + Mesh0 [SkinnedMeshRenderer]
| + Mesh1 [SkinnedMeshRenderer]
+ Model
+ Physics

メッシュアセット同様、例えメッシュが1つで合っても新構成を採用しています。
メッシュ1つの場合には前回構成を維持する方が良ければお知らせ下さい。

心配事
====
この構成でMecanimに耐えられるのか。

メッシュアセットはMeshesディレクトリなのに、SkinnedMeshRendererがMeshノードはちぐはぐ感が…(今気付いた)。