表情差分の抽出と切り替え

2019/02/17追記
Tightメッシュにも対応しました

ノベルパートでの立ち絵での表情の切り替え テラシュール御大でも何度かネタにされているあれです。

tsubakit1.hateblo.jp

これについて、自分は「表情差分とそれ以外がちゃんと分かれたメッシュを作って顔の箇所のUVを切り替えればよいのでは」と長年うっすらと考えていました。 9sliceの真ん中を書き換えるようなイメージです。

で、このたび実装してみました。

github.com

どんな感じか

アセットの準備

何はともあれ表情切り替えのある画像を用意します。 以下はUnity-Chanの公式よりありがたくいただいてきました。

f:id:enrike3:20190216213215p:plain
assets

次にぎっはぶのコードをプロジェクトに突っ込みます。 コンパイルが通ったらProjectViewを右クリックして、「Create → ScenarioCharacterAssetGenerator」をぽちります。

f:id:enrike3:20190216213729p:plain
creategenerator

これは表情差分の抽出、画像のパッキング、Meshの生成をするためのGenerator (ScriptableObject)が作られます。 インスペクタは下図のようになっています。

f:id:enrike3:20190216214337p:plain
generator

こやつに、画像と出力パスを設定します。 立ち絵のデフォルトになる画像をBaseTextureに、差分をDiffTexturesに、出力先をDestination Pathに入力します。 Block Sizeは圧縮テクスチャのブロックサイズです。DTX1/DTX5, ETC2, ASTC(4x4)あたりを使うなら初期値4のままでかまわないです。RGBA16やRGBA32などの圧縮なしや減色のみのフォーマットを使うならBlock Sizeは1としても良いです。 Diff Rect, Diff Rect Adjusted By Block Sizeは差分抽出中に勝手に入る数値です。デバッグ用に表示してます。

「表情差分画像生成」ボタンをポチると、マルチスプライトが生成されます。

f:id:enrike3:20190216215044p:plain
scm_multisprite

表情差分側のほうはBlockSize分の余分なピクセルが周辺にあります。これは圧縮テクスチャ使用時、引き延ばしたときにBilinearフィルタで絵のつなぎ目が破綻しないように、という処置で今回のこだわりポイントです。単なる色の引き延ばしであるExtrudeではダメでした。

f:id:enrike3:20190216215219p:plain
aroundblocksize

パックされた画像が出来上がったら「Mesh生成」をぽちります。パック画像と同じフォルダにメッシュができます。

実際に使用する

MeshRendererにScenarioCharacterMeshコンポーネントを貼り付け、表情のSpriteを全部ぶち込みます。 Materialは_MainTex_Colorを指定できるものならなんでもよく、つまりSprites-Defaultを使えます。 MeshFilterには生成したMeshを指定してください。

f:id:enrike3:20190216215814p:plain
scm_scminspector

SpriteIndexに、使いたい表情のIndex値を指定すれば表情が切り替わるはずです。 なんか描画がおかしかったら一度プレイモードで再生してみてください。わりと起きます。ExecuteInEditMode難しいんじゃい…

f:id:enrike3:20190216220235p:plain
rendering

5枚の板ポリが含まれたメッシュをただ描画するだけで、画像もパックされてますので当然ドローコールは1です。板ポリ1枚描画するのと大差ないといっていいでしょう。

f:id:enrike3:20190216220412p:plain
stats

良い手法かどうか

メッシュを準備する手間があるかわりに描画方法としてはとても単純で素直なものなので、全体と表情差分を別描画する方式と違って半透明の問題が起きません。

ただし結構大きな欠点として、TightメッシュではなくFullRectで描いているので透明領域のピクセルの塗りが無駄オブ無駄です。フィルが良くない。

よって、頂点数を増やしてフィルを落としたいなら結局Tightメッシュ+表情別描画+SpriteMaskのテラシュール方式りに落ち着きそうな気もします。有料でいいなら宴のダイシングが描画の素直さとフィルの削減で一番バランスが良いかなぁ。