mmd-for-unity-proj/mmd-for-unity — pull request #30 by eral (2013-12-21 19:46:55+00:00)
Title: 透過材質の描画改善

# 透過材質の描画改善
透過する材質の描画を改善しました。
大きく分けて下記の3つの対応が行われています。
- エッジ付き材質が半透明ソートを無視する不具合の修正
- マテリアルの透過判定を最適化
- カスタムレンダーキュー対応

個別に解説します。

## エッジ付き材質が半透明ソートを無視する不具合の修正
シェーダー付けでレンダーキューの指定が出来ます。
エッジ無し透過シェーダーは`Transparent`キューなのに対し、エッジ有り透過シェーダーは`Transparent+1`キューと1テンポ遅延させていました。
これに依り半透明ソートが崩れている様に思いましたので、全て`Transparent`キューにしました。
多分こちらの方が化ける事が少ない様に思います。

## マテリアルの透過判定を最適化
その材質を透過として扱う必要が有るかどうかを判定するには、下記を考慮しなければいけません。
- 材質拡散色の非透過度が`1`未満
- 材質モーフに依って材質拡散色の非透過度が`1`未満に為る
- テクスチャの透過が含まれる領域をUV参照する
- UVモーフに依ってUV参照が透過が含まれる領域に移動する

Unityでは1つのシェーダーに非透明と透過を混在させる事が出来ません(と思う…)ので、エッジ周りの透過も考慮する必要があります。
故に下記も考慮しなければいけません。
- 材質エッジ色の非透過度が`1`未満
- 材質モーフに依って材質エッジ色の非透過度が`1`未満に為る

これらの考慮事項に対応しました。
これで透過判定の誤爆率は大分減るかと思います。

ただし、高速化の為に幾つか簡略化していますのでそれに依る誤爆が発生する可能性は有ります。
高速化の為に行った簡略化は下記と為ります。
- UV参照に於けるテクセル透過確認を全領域行わない
- UVモーフの中間レベルを考慮しない
- UVモーフで範囲外レベルを考慮しない
- UVモーフを複数持つ場合の組み合わせを考慮しない

個別に解説します。

### UV参照に於けるテクセルを全領域行わない
3角形ポリゴンが与えられた場合、其処からは3つのUV座標が取得出来、それらはテクスチャ上で3角形を構成します。
本来ならその3角形に掛かる全てのテクセルについて透過を確認する必要が有ります。
テクスチャ解像度とテクスチャ上の3角形の大きさ(≠3角形ポリゴンの大きさ)に依っては確認するべきテクセルは相当数に上ります。
現在の実装では全テクセルの確認を行っておらず、下記の代表する7点のテクセルのみ確認しています。
- 3頂点
- 重心点
- 3辺の中心点

### UVモーフの中間レベルを考慮しない
UVモーフは`0`から`1`迄の値を持ちます。
`0`の時と`1`の時に参照する領域は多くの場合違っており、`0`と`0.001`でも違っている可能性があります。
`0`から`1`迄の全てのレベルは使用される可能性が有る為、それらで参照するテクセルは全て確認しなければいけません。
現在の実装では6角形での確認は行っておらず、中間レベルを全て無視して`0`と`1`のそれぞれ2つの3角形のみで確認しています。

### UVモーフで範囲外レベルを考慮しない
グループモーフを組み合わせればモーフのレベルは`1`を超える事が出来ます。
しかし現在の実装では、作用するグループモーフを持っていたとしても`1`を超えた領域は確認しません。

### UVモーフを複数持つ場合の組み合わせ計算の無視
複数のUVモーフが同一頂点に対して作用する場合、合算して作用します。
U方向に`+0.5`するモーフとV方向に`+0.5`するモーフが有る場合、組み合わせれば`U+0.5,V+0.5`領域を参照出来ますが、現在の実装では確認しません。

## カスタムレンダーキュー対応
シェーダー付けでレンダーキューの指定が出来る事は前述しましたが、スクリプト上ではマテリアル単位で設定出来ます。
マテリアル全てに厳密な描画順を設定する事で半透明ソートに依存せず、MMDと同じ登録順で描画する事に対応しました。
ただし後述する欠点の為に変換直後は無効化されています。
有効にするにはMMDEngineのInspectorに在るRender QueueチェックボックスをONにします。

### 利点
モデル単体で見るとMMDの描画順と完全に一致する為、化ける事はまず発生しなくなります。
化身バレッタ式セルシアナさんを正面から見た場合、半透明ソートでは眉毛と睫毛が欠けますがカスタムレンダーキューではそれも改善されます。

### 欠点
半透明ソートが効かなくなる為、モデル外の半透明オブジェクトと喧嘩する場合が有ります。
化身バレッタ式セルシアナさんの手前に半透明のCubeを置いた場合、半透明ソートでは正常に映りますがカスタムレンダーキューでは前後関係がおかしく見えます

# テストモデル
- あにまさ式初音ミク(MMD Ver.8.03(x64)付属)
- Lat式ミク(Ver2.3)
- mqdl式初音ミクXS(rev.c)
- 七葉1052式ピッチングP改変初音ミク(Ver1.03) *(エッジがおかしい)*
- えと式初音ミク(ver3.01β)
- Tda式初音ミク・アペンド(Ver1.00)
- 七葉1052式箔鳥居改変初音ミク1052C-Re(Ver.1.8a)
- おんだ式初音ミク(Ver.1.21)
- ぴくちぃ式ミク(v1.4)
- ゆきはね式初音ミク(Ver2.32)
- けみか式初音ミク(1.2)
- そむにうむ式初音ミク(BDA06e Rev.000-β002)
- ままま式DieIrreKatze.改変EARTH改変Appearance Miku WIM(改)(2013/08/25)
- ままま式GUMIβ V3 Whisper ver (2013/06/03版)
- ula式巡音ルカ(Ver3.11)
- ula式トゥイードル・ダム(Ver.1.00)
- ula式トゥイードル・ディー(Ver.1.00)
- お宮式結月ゆかり(ver.4)
- 化身バレッタ式セルシアナ(Ver4.8)
- BTA/kelorin jo式ケロリン町(ver2.02)
- ゆづき式天体観測儀ステージ