
【制作記録】Live2Dで不可能図形を動かす
はじめに
ここ最近、Live2Dを触ってみたいなと思っていたところ「そういえば不可能図形ってLive2Dで動かせるのか?」とふと思い立ったので作ってみることにしました。本記事ではその制作過程をまとめています。
初心者なのでいろいろ拙いところがあるかもしれません。あと先行研究が既にあったらそれもすみません。
不可能図形について
Wikipediaで不可能図形は以下のように立項されています。
不可能図形 (ふかのうずけい、英: impossible figure) または不可能物体 (ふかのうぶったい、英: impossible object) は一種の錯視であり、視覚によって3次元の投影図として解釈されるような2次元の図形だが、実際にはそのような3次元物体は(少なくとも視覚が解釈した通りには)実在不可能である。
上記のように、3次元上で正確に再現できない図形のことを不可能図形と言います(実際には、いろいろ工夫すると特定の角度からは不可能図形に見える立体があったりします)。代表的なのはペンローズの三角形とか。
扱う図形について
不可能図形にもいろいろありますが、今回はこういう立方体(の辺)をベースにした図形がくるくる動くようにします。

透視投影か平行投影か
3次元空間の物体を2次元平面に投影する際、主に透視投影と平行投影の2種類のやり方が考えられます。
透視投影は平行線が消失点で交わり、遠くのものは小さく・手前のものは大きく見える投影法で、より自然な見え方になります。一方、平行投影は平行線が交わらず、遠近感のない投影方法になります。
平行投影の方が手前と奥の辺がきれいに重なるため、辺の前後が入れ替わる際の違和感が少なそうです。また、パースのついていない図形の方がLive2Dでの作業がやりやすそうであるという理由で、今回は平行投影を採用しています。

また、平行線の傾きはすべて等しい。
計画段階
実際にLive2Dでの作業に入る前に、まず必要な材料を揃えます。最終的に立体がぐるぐる回るようにしたいので、いろいろな角度で不可能図形がどのように見えるかを考えます。
それぞれの角度での見え方
とりあえず、代表的な角度を選んでどのように図形が見えるのか検討します。元の立体から不可能図形にする方法はいくつか考えられます。例えば、下の例では3種類ほど考えられますが、見栄えや実装のしやすさなどを考慮して、その中から1つを選びます(下の例ではパターン1を選びました)。

角度を変えた際の見え方を手描きで考えるのはしんどいので、Blenderを使います。下図のような図形を作って角度を変えながら撮影し、撮影した画像を加筆修正して不可能図形に描き換えます。

縦方向の回転角を7段階、横方向の回転角を5段階に分けて、合計35個の図形を作成しました。角度ごとに図形を並べたものを以下に示します。

(x と y は、Live2Dのパラメータの角度Xと角度Yに対応しています。
ここでは横回転・縦回転のことだとだと思ってください)
沢山あるように見えますが、不可能図形になっているのは上下中央にある12個の図形のみです。さらに言うと、重要なのは (x, y) = (30, 60) と (x, y) = (30, 30) の2種類のみで、あとはこの2つの派生または上下左右反転の図形になっています。
上下と左右をそれぞれ繋ぐと、回転をループさせることができます。上下回転の場合は細部の形が異なる図形を繋ぐことになるので無理矢理感がありますが、これ以上作らないといけない角度を増やすのはしんどいので妥協しました。今後、こういう誤魔化しがいろいろと出てきます。
各状態を繋ぐ方法
上図で挙げた図形を繋ぐことができれば図形の回転が実現できます。しかし、現時点で懸念がいくつかあります。
例えば、回転の途中で辺の前後が入れ替わる場合、どこで切り替えるのか。

また、辺が重なるところやパーツがずれ込むところなど、図形が変に見える角度はあまり見せたくないが、どうすればいいか。

これらの懸念点に対する解決策として、以下の2つを考えました。
他の状態と繋ぐために、辺が重なる時に画像を入れ替える
辺が重なる付近の箇所でパーツを瞬時に入れ替えることで、パーツの切り替えが比較的自然に見えるようになるのではないかと考えました。

中途半端に辺が重なるところや、パーツがずれ込んで形が変に見える部分は速く動かす
中途半端な見え方の部分は速く回転するようにし、きれいに見える部分はゆっくり回転するように設定できれば解決できそうです。

これらがうまくいけば、不可能図形を動かすことができそうです。実際に成功するかはLive2Dを触ってみないと分からないので、ここで制作に移ろうと思います。
制作段階① 可能図形を動かす
さて、それではいよいよLive2D上での作業に入ります。
まずはLive2Dに慣れるためにも、普通の立体を作ることから始めようと思います。その後、手を加えて不可能図形に仕上げます。

パーツ分け
図形に動きをつける前に、まずいくつかのパーツに分割します。この後不可能図形にすることも考慮して、合計で12個のパーツに分けました。大まかには、手前のパーツ・中間のパーツ・奥のパーツの3種類に分類されます。

パーツa1~a3、b1、c1 は 0 ≦ y ≦ 90 (上半分)の領域のメインパーツです。一方、パーツa4~a5、b2、c2 は -90 ≦ y ≦ 0 (下半分)の領域のメインパーツとなります。Cパーツの青い面が2つに分かれているのは、この後不可能図形を作るための工夫です。
キーフォーム割り当て
Live2Dでは、パラメータにキーを追加し、その時点での形状をキーフォームとして割り当てることで動きをつけることができます(キーを追加していないところは、いい感じに補完してくれます)。
分割したパーツにそれぞれキーフォームを割り当てていきます。Blenderで撮影した画像を下絵にして、パーツを変形させます。

キーフォームを割り当てているところ
面にめちゃくちゃ文字が入っているのですが、一部分が変に伸びてしまったりパーツの裏表が分からなくなったりしないためのものです。見栄えが悪いので、後で画像を差し替えます。
最終的に、x方向に5つ、y方向に7つ、合計35個のキーを追加しました。キーの位置は計画段階の図に基づき、x = 0, 30, 45, 60, 90 と y = 90, 60, 30, 0, -30, -60, -90 に配置しています。
これ以上キーを増やすのは手間がかかるため、見た目的にも問題がない35個で決定しました。逆に、キーの数を減らすと補完された中間状態がかなり変形して見えるため、この程度の数が適切だと判断しました。

キーの数が9個の状態。下絵と比べてかなり潰れてしまっている。
キーフォームの登録が全て終われば、普通の立体こと可能図形の完成です。

制作段階② 不可能図形にする
さて、前の工程で作ったものを元に、不可能図形にしていきたいと思います。
不可能図形に見せるためには、奥のパーツを手前に持ってくる必要があります。それを実現するためにLive2Dの描画順という設定値を調整します。
描画順の変更
描画順は各パーツに割り振られる値で、値が大きいほど手前に描画されるようになります(同じ値の場合、パーツ一覧で上に来ているものが手前に描画されます)。例として、x=30,y=60での可能図形の各パーツの描画順は以下の通りです。

手前のパーツの値は大きく、奥のパーツは値が小さいことが分かると思います。この描画順を使って、奥のパーツを手前に持ってきたいと思います。
具体的には、各パーツの描画順を以下のように設定しました。0 ≦ y ≦ 90 (上半分)の領域と、-90 ≦ y ≦ 0 (下半分)の領域とでメインのパーツが異なるため、分けて記載しています。

ポイントは、手前のパーツ(Cパーツ)の一部が下にあることです。中間パーツ、奥パーツ、手前パーツの順になることで、奥パーツが手前に来るように見えます。
描画順は、各キーに対しても割り当てることができます。つまり、「この角度では手前に持っていきたいけど、こっちの角度では奥に見えるようにしたい」ということができます。奥のパーツ(Aパーツ)は、角度に応じて前後を入れ替えるため、400~650の値を行き来します。
パーツの切り換え
キーを割り当てていない箇所はうまく描画順が連続的に変化するように繋いでくれます。このままだと、例えば以下の様に思いがけないところで描画順が変更されたりします。

そのため、もう少しキーを増やし、描画順の切換えを行う場所を作ります。上図の場合、上に縦回転させると奥のパーツが元に戻ってしまいます。そこで、下図のように y = 78.9 と y = 79 でキーを追加し、辺が重なるぎりぎりのところまでパーツが切り替わらないようにします。

キーを近いところに打つことで、y = 79 の付近で瞬間的にパーツが奥に移るように見せます。
また、計画段階で書いたように、上下回転の際には辺が重なるタイミングでパーツが入れ替わるようにしたいです。例えば下図の場合、パーツa3は下方向に回転する際に奥から手前に移動するようにしたいです。

そのため、辺が重なる y = 49 あたりにキーを打ち、描画順を設定します。さらにそのすぐ近くの y=48.9 でキーを打つことで、ここでも瞬間的にパーツが入れ替わるように見せます。
他の場所も同様に適宜キーを追加し、描画順を設定します。キーの追加場所は、実際に図形を動かしつつ必要そうなところに入れていきます。
※どうしてもきれいに行かないところがあり、ここで急遽パーツを追加しました。

キーの移動
パーツが切り替わるところ、辺が重なるところなどはあまり見せたくありません。パラメータ領域の中で、図のグレーになっている所がきれいな不可能図形として見える(おおよその)範囲です。

Live2Dでは、既に設定したキーの位置を移動させることができます。グレーの部分をなるべく見せるため、キーを移動させ、グレーの領域を広げます。こうすることで、辺が重なるところは素早く動き、きれいなところは長く見えるようになります。

制作段階③ 仕上げ
一応完成しましたが、このままだと耳なし芳一みたいな見た目なので画像を差し替えてきれいにします。
画像の差し替え
差し替えの際の注意点として、縦回転と横回転をそれぞれループさせているため、赤色の面と緑色の面は同一色である必要があります。

今回は全ての面をグレー一色にしました。画像を差し替えて、アニメーションをつけて完成です。

画像の差し替え その2
単一色だと見づらいかなと思ったので、ループを犠牲にして3色に塗り分けました。こっちの方が見た目はきれいに見えますね。

横方向の回転が物足りない感じがありますが、まあこれでもいい気がします。
反省点とか感想とか
計画段階での不可能図形の見え方をもう少し変えていれば、動かすのはより簡単になったかもしれません。例えば以下のように変更すると、奥のパーツを切り替える手間が減少するのでやや簡単かも。
ただあんまりやりがいはないかもな、と思って今の形にしました。

面の塗り分けをするために回転のループができなくなったのが心残りです。パーツを増やしたりパーツ分けの仕方を変えればできそうだと思ったけれど、面倒で諦めてしまった。
Live2Dを使い慣れている人から見れば見苦しいところが多々あったかもしれません。パーツの切り替えとかは調べればもっといい方法があるかもしれないですね。今回の制作でLive2Dには少し慣れたので、今度は人間のキャラみたいなのも作ってみたい。