挿絵画家になろう(その11)


「挿絵画家になろう(その11)」です。
これまでBlenderのアドオン、MB-Labの啓蒙として記事を連ねてきました。
MB-Labを使って秀逸な少女キャラクターのメッシュオブジェクトを生成し、VRoidStudioの髪をインポートして装着させ、そこそこの服を着せ、キャラクターのマテリアルも弄れるようになり、表情も変更できるようになり、同梱のポーズを組み合わせて新しいポーズも作れるようになりました。
そして服に関しても、まあそれなりに用意できるようになりました。

そろそろ背景が欲しいな、と思います。
単に背景と言っても色々です。
単色塗りつぶしやグラデーションハイライトといった2Dペイントツールでの描画でも良いし、当然ガチンコで屋内屋外の風景を描いても良いです。

ただ、我々は本来「(自称)小説家」です。
自分の小説に挿絵を付けることが目的です。
当然挿絵を書く時間は最小限に留め、その分小説執筆に時間を割きたいですよね?
そのためのいくつかのソリューションを考えました。
ただ残念ながら無料ではありません。
無料でもできなくはないですが、そこはクオリティとのトレードオフになりますね。

本記事はWindows10のChrome推奨です。
その他の環境でどうなるのかは検証していません。
以下のWEBGLコンテンツは参照できますでしょうか?

これはUNITYで作成したWEBGLコンテンツです。
正常に動作していれば、海と空の動く風景が表示されます。
海は波たち、空には雲が流れます。
このような風景が簡単に作れてしまうのです。
UNITY自体は(個人ユースであれば)無料で使えるのですが、今回は以下の有料アセットを使っています。

aquas-water-river-set
massive-clouds-screen-space-volumetric-clouds

屋外風景を考えるに、先ず超遠景としての空や大地もしくは海があり、それよりも近い遠景があり、地形を特徴付ける中近景があり、周囲環境があるわけです。
我々は人物モチーフをMB-Labの3Dキャラクターにする決心をしました。
では風景もある程度は3Dで固めていきましょう。
そのための超遠景に関して先ずは考えよう、というわけです。

上のWEBGLコンテンツをChrome上でマウスオーバーしてアクティブにし、[p]キーを押してみてください。
skyonsea_panorama.png という画像ファイルがダウンロードされれば期待動作です。
適当な画像ビューアで開くと以下のようなパノラマ画像であることが分かります。

上のWEBGLコンテンツは空と海の風景をパノラマ画像として生成するツールでもあるのです。
タイミングを選んで [p]キー を押すことにより、希望の雲の画像を得ることができるのです。

3Dキャラクターを最終的にどのプラットフォームで作品に仕上げるのかは検討すべき課題です。
ただし、今回は結論を出しません。
と言うか、空と海をUNITYで作っておきながら、今回はUNITYでどのように風景を作るのか、という話をしたい訳でもありません。
あくまでも風景画像をBlenderで表示してとりあえずは空と海がある風景の中、3Dキャラクターをレンダリングする方法に関して述べるだけです。

さて、パノラマ画像のサンプルを得ることができました。
この画像を任意のプラットフォームに持っていき、背景に使えば良いわけです。
UNITYのSkyBoxに再移植することもできますし、Daz Studio等、たいていの3Dインテグレーションツールで表示させることができます。
今回はBlenderの背景にする方法を説明したいと思います。

Blenderでの設定方法は簡単です。
先ずオブジェクトモードであることを確認してプロパティウインドウのワールド(青い円のマーク)を選択します。

「サーフェス」の項の「ノードを使用」をクリックします。

「サーフェス」の項に背景が設定されました。

「スクリーンレイアウトの選択」から「compositing」を選択します。

「ノード」を「マテリアル」、「シェーダーを取得するためのデータタイプ」を「ワールド」に切り替えます。

[shift+a]で現れる「追加」メニューから以下を追加します。
・テクスチャ:環境テクスチャ
・ベクトル:マッピング
・入力:テクスチャ座標
そして以下のように連結させます。

環境テクスチャにパノラマ画像を読み込みます。
3Dビューの「3Dビューのシェーディング」で「レンダー」を選択すると背景が描画されます。
もし青っぽくなるけれど全景が表示されないという場合は投影方式が「平行投影」となっています。
テンキーの[5]キーを押して「透視投影」に切り替えます。

後はノードの「マッピング」を調整して背景画像を調整します。
色々極端な設定にすると変化があって面白いです。

MB-Labのキャラクターの背景にしてみました。

いかがでしょうか?
パノラマ画像があれば、それを背景に設定できました。
別に普通の画像でも背景にできますが、パノラマ画像だとアングルやズームが思いのままですので自由度が高いのが良いです。

問題はどのようにしてパノラマ画像を入手するかです。
WEB上では無料素材としてパノラマ画像を公開していらっしゃる方もおられます。
気に入るものがあればそれを使うのでも良いでしょう。
気に入ったものが無いのならば自分で作成するという手もあります。
TwinMotionでも天候を決めてパノラマ画像で出力することができます。
素材を用意できるのならばTwinMotionで背景画像を作るのは良い選択かもしれません。

今回UNITYを使いましたが、正直なところ小説家になろうの諸兄姉にはお勧めしていません。
理由は満足する画像を作れるようになるまでのハードルが高いことです。
無料で希望する絵作りをするにはかなりスキルを磨く必要があります。
もしくは有料アセットを購入する必要があります。
たとえ有料アセットを購入したところで、バージョンやアセット毎の組み合わせがあり、なんかよく分からない障害にぶつかります。
UNITYってバージョンアップが激しくて古いアセットは新しいバージョンで使えなくなっていることが多いんですよね……。
あのアセットとこのアセットを組み合わせれば、と思いホクホクしていると「なんでこうなる?」ということが多々あり、解決のためにログ見たりググったり、そして夜は更けてゆく。
好きなら良いんですが、誰もがそんなマゾという訳じゃないですよね?
UNITYって本当によく分からない。

上のWEBGLコンテンツで生成した画像は小説の挿絵背景としてならば自由にお使い頂いて構いません。

今回はこれで終わりです。
UNITYでWEBGLコンテンツとしてパノラマ画像を生成・ダウンロードする方法に関しては別方面で需要があるかもしれません。
機会があれば別記事にまとめたいと思っています。
また、時間があれば[その12]を書きたいと思います。


挿絵画家になろう(その10)


「挿絵画家になろう(その10)」です。
これまでBlenderのアドオン、MB-Labの啓蒙として記事を連ねてきました。
MB-Labを使って秀逸な少女キャラクターのメッシュオブジェクトを生成し、VRoidStudioの髪をインポートして装着させ、そこそこの服を着せ、キャラクターのマテリアルも弄れるようになり、表情も変更できるようになり、同梱のポーズを組み合わせて新しいポーズも作れるようになりました。

今回は前回に引き続き、襟付きのワンピースを作ります。
今回はキャラクターの体のメッシュを利用して服を作成します。

Anime_female(F_AN02)でキャラクターを生成します。

服のベースはdefaultのキャラクターから作ります。
ポーズをt-poseにします。

t-poseにするのは服の作りやすさからです。
最終的なシルエットの美しさはa-poseから作ったほうが良いのですが、腕や足の角度があるので細かな修正が難しくなるのです。

あとはdefaultのままFinalizeするのですが、接頭語だけは分かりやすい名前を指定します。
ここではmannequin_gilr_1としておきます。

このキャラクターのメッシュの一部を素材として加工することにより服を作ります。
ただしMB-Labで生成したメッシュには各種のmodifierが適用されていて、メッシュ流用時に悪影響が出ます。
Modifierの影響を外す方法はいくつかあるのですが、ここでは簡便に一旦Waveフォーマットでエクスポートすることとします。
Obj形式は複雑なエフェクト類が一切無いのでModifierの影響が全てなくなります。

適当な名前を付けてエクスポートします。
ここではmannequingirl1.objとしておきます。
必ず「選択物のみ」にチェックを入れます。
これを忘れるとカメラやランプなどの余計なものが混入します。

Objファイルのエクスポート後、このBlenderプロジェクトはしばらく使わないので保存しておきます。
ここではmannequin_girl_1_base.blendとしておきます。

mannequin_girl_1_base.blendは暫く使わないので閉じてしまって構いません。

Blenderで新規のプロジェクトを開きます。
そして mannequingirl1.obj をインポートします。

単なるメッシュオブジェクトとしての mannequin_girl_1_body_MBLab_anime_femaleが読み込まれます。

このメッシュオブジェクトを素材にしていくわけです。
メッシュオブジェクトを目的に応じてコピーします。
目的とは原型ベース、メッシュ間引き用、ワーク用等です。

一つは原型ベースとして確保しておきます。
プロパティシェルフの[レンダーレイヤー]ボタン(二枚の重なった書類のボタン)を押下します。

オブジェクトモードになっていることを確認して mannequin_girl_1_body_MBLab_anime_female を右クリックで選択します。
[shift+d]キーを押して mannequin_girl_1_body_MBLab_anime_female をコピーします。
マウスを動かすとコピーされていることがわかります。

[esc]キーを押すと移動がキャンセルされます。
この状態ではコピーした方の mannequin_girl_1_body_MBLab_anime_female.001が選択されています。
[m]キーを押すとレイヤーの移動となります。

左上の枠がdefaultのレイヤなのでそれ以外の枠を選択します。
ここでは上段左から5番目のレイヤを選択します。
プロパティシェルフの[オブジェクト]で mannequin_girl_1_body_MBLab_anime_female.001 をmaterial_baseにリネームしておきます。

material_base を編集します。
5番目のレイヤ、編集モードであることを確認します。
3Dビューのシェーディングはソリッドとします。
服の素材として不要な部分を消していきます。
先ずは首から上。
首の一部分を[alt]キーを押しながら右クリックでラインの選択を行います。

頂点を削除します。

首から上が分離します。
首から上のメッシュにマウスオーバーさせて[l]キーを押下して選択していきます。

歯茎や舌のメッシュが残りますが同様に削除していきます。

首から上が消えたら、次は体の半分を消します。
意図はミラーモデファイアで左右対称にするためです。
ちなみにdefaultのメッシュは意外なことに左右対称ではありません。

ライン選択→頂点の削除→メッシュの選択→頂点の削除で右半分を削除します。

どんどん消します。
なんか楽しくなってきます。

黒いマテリアルだと作業しにくいので適当な色に変えます。

現状のメッシュは目が細かすぎるので間引きます。
具体的な作業としては一本置きにライン選択をして「削除」→「辺の溶解」を行います。

これで素材ベースとしてはいい感じになりました。
ミラーモデファイアを適用します。
オブジェクトモードに戻り、プロパティシェルフのモデファイア―からミラーを選択します。

XをチェックしてX軸で左右対称にします。

このまま「適用」ボタンをクリックして適用します。

プロパティシェルフのレンダーレイヤ―を選択し、レイヤーのシーンで1番目のレイヤを重ねます。
([shift]キーを押しながら左クリックすると複数のレイヤを選択できます。)

素材ベースはメッシュを間引いているのでオリジナルより若干小さくなっています。
素材ベースを体より大きくするために法線方向に拡大します。
material_baseオブジェクトが選択されていることを確認してから編集モードに切り替えます。
オブジェクトにマウスオーバーさせて[a]キーを押して全選択します。

[alt+s]キーを押し法線方向への拡大とし、[↓]を三回ほど押します。

膨らみました。
ギリギリを狙うよりは体から明確に服が離れる程度にするほうが良いと思います。

ここからはメッシュを変形させていきます。
テンキーの[3]キーを押して真横からのビューにします。

この先の作業は基本的に一番下のラインを[e]キーで延長、拡大、回転で調整しながら下に伸ばしていきます。

上半身側の一番下のラインを[alt]キーを押しながら右クリックして選択します。

[e]キー→[z]キーを順番に押し、[下]キーを押して服を下に伸ばします。

基本、[e]キーには[z]を組み合わせて下へだけ延長、[s]キーや[g]キーも[x][y][z]と組み合わせて方向を管理してゆきます。
正直ここは経験が要りますが、そんなに難しくはありません。
後でモデファイア―をかけますのでシルエットを整えることに専念します。

とりあえず以下のように変形させました。

イメージとしては体の線を強調させすぎず、スカートがやや広がるワンピースです。

襟もつけましょう。
首の一番上の線を選択し、[e]キー、[s]キーを順番に押してマウスで広げます。

適当な大きさに広がったら[enter]キーで確定させます。
辺ループカットで適当なサイズに分割します。

襟の前部分のメッシュを削除します。

袖も加工します。
両手分の袖を同時に作りたいので再度半分を消し、ミラーモデファイア―を適用します。

袖を作ります。

襟を整え、ミラーモデファイアを適用します。

次にUVマップ用のシームを付けていきます。
シームとはUVマップ展開したときに島として分離したい境界線です。
ワンピースのデザインとして、前回に合わせて襟と袖口は白、その他は紫ということにしましょう。
シームを付けたい線を選択します。
ある程度部分に分けないと[スマートUV展開]で微少な島が量産されてしまい苦労します。

[ctrl+e]キーを押して辺のメニューを出し、[シームを付ける]をクリックします。
シームを付けた所が赤い線になります。

[a]キーで全選択して[u]キーを押下し、UVメニューを出します。
[スマートUV展開]をクリックします。
[島の余白]は0.01(1cm)程度にします。

UV画像エディターでUVを確認します。

新規画像は全面黒かと思います。
UVマップには一見どこの部位か分からないほど細かく島が生成されています。
服の造形がテキトウであるため、エッジが多く、分割されてしまうのです。
これを避けるにはスムースな造形を心掛ける必要があります。
しかしそれは「簡単に早く作る」という造形意図に反するので悩ましいところです。

複雑なUVマップなので、単純にいくつかの色を塗るだけならまだ良いのですが、縞模様の服を作りたい場合などは苦労することでしょう。

UVマップ用の新規画像を開き、とりあえず[onepiece]と名前をつけます。
全体を紫で埋めたのち、袖と襟を白く塗ります。

マテリアルの設定で、[onepiece]の画像を割り当てます。

色が反映されます。

後はクロスモデファイアを適用します。

mannequin_girl1_MBLab_anime_femalにコリジョンモデファイアをかけます。

onepieceのほうにクロスモデファイアをかけます。

仕上がりは以下のような感じです。

ライティングが悪いのでマネキンではなく、デフォルトキャラクターに着せてみましょう。

胸の形など、必要以上にはボディラインが強調されず、でも体形に沿った綺麗なシルエットになっています。
これは縫合スプリングが前後左右への締め付けが発生するのに対して、重力による布の落下しかないためです。

縫合スプリングを用いる方法より、こちらの方法の方が シルエットをコントロールするのが圧倒的に楽です。
襟の形も、少々の風や乱流があっても然程は乱れません。
襟足の高いデザインでもある程度はコントロール可能です。
服の造形はシルエットを制御する程度のクオリティで良く、後はクロスモデファイアがいい感じに整形してくれてしまいます。

以上の作業ですが、慣れると一着三十分程度で行えます。
途中までの成果物があればキャラクターごとに流用可能なので、シルエットの直しや、襟の形の直し等であればさらに短時間で新しい服を生成可能です。

デメリットは以下。
・UVマップの島が複雑。
・キャラクターごとに作りなおす必要がある。
・メッシュのライセンスを考慮する必要がある。

MB-Labのメッシュを流用するので、当然ライセンスに関してはMB-Labのライセンスの影響を受けると考えたほうがよいでしょう。
服を配布したい場合や3Dゲーム等に使う場合はMB-Labのライセンス条項に従うべきかと。

以上前回と今回で、アプローチの違う二つの方法で、ほぼ同じ形状の襟付き長袖ワンピースを作成しました。
どちらにもメリット・デメリット、得意・不得意があることがお分かり頂けたかと存じます。
どちらが正解というものでもなく、組み合わせていけばよいのだと思います
とはいえ、もっと簡単な方法はないものかと……。

と、いうことで今回は終わりです。
時間があれば[その11]を書きたいと思います。


挿絵画家になろう(その9)


「挿絵画家になろう(その9)」です。
これまでBlenderのアドオン、MB-Labの啓蒙として記事を連ねてきました。
MB-Labを使って秀逸な少女キャラクターのメッシュオブジェクトを生成し、VRoidStudioの髪をインポートして装着させ、そこそこの服を着せ、キャラクターのマテリアルも弄れるようになり、表情も変更できるようになり、同梱のポーズを組み合わせて新しいポーズも作れるようになりました。

で、やはりネックは服なんですよね。
その2」でネット上の情報をもとに縫合スプリング機能を使って簡易的な袖なしTシャツを作る方法を紹介しました。
また「その4」ではワンピースを作る方法を紹介しました。
でも襟は無いし、半そでだしで多分これだけでは満足できないですよね?

私としても服を自由に、そして簡単に作る方法を模索し続けているのです。
でも、無料の良いソリューションを見つけることができていません。
もしご存じの方がいらっしゃったら是非ぜひお教えください。

縫合スプリングを使う方法は、私自身、あまり良い方法とは思っていません。
Tシャツなどの簡単なものならば良いのです。
しかしやってみると分かるのですが、少しでも凝ろうとすると難易度が跳ね上がっていきます。

私も縫合スプリングを知った当初は、実際のドレスシャツの型紙から各パーツを作れば良い、なんて考えていました。
しかしパーツの数が増えると、縫合線を結ぶ事自体が難しくなります。
襟や袖を離れたところから縫合しようとすると移動の途中で変形してしまい、もとの形状が失われてしまいます。
綺麗に縫合するには変形後の形状を合わせる必要があり、複雑な形にするにはかなりの研究が必要です。

実際の縫製用型紙を作るのも難しいのでしょうが、縫合スプリングではまた別の難しさがあるのだと思います。

縫合スプリングで複雑な服を作るには、それはそれで深く険しい道なのだと思います。

それでも、単純な形状ではそれっぽい服を作成できるのが縫合スプリングの良さだと思います。
今回と次回で、同じような襟付きの長袖ワンピースを別の方法で作成していき、差を見ていきたいと思います。

ということで今回は縫合スプリングを使った方法です。
変形前の素材を以下に置いておきます。
clothe_onepiece_spring_mat.zip

この素材はMB-LabのAnime_Female(F_AN02)のデフォルトキャラクターに合わせて作成しました。
ZIPファイルには以下のファイルが梱包されています。
clothe_onepiece_spring_mat.obj
clothe_onepiece_spring_mat.mtl
onepiece_txt.png

MB-Labで適当なキャラクターを生成して後にインポートしてください。
次のアニメーションのように首に丸い輪っかを通すようにして全体を整えます。

マテリアルの設定は以下のようにします。

UVマップが非常にシンプルです。
縫合スプリングで服を作成する場合、元の形状が平面であるため、[スマートUV投影]でもほぼメッシュ通りの分かりやすいUVマップとなります。
色を塗るにしても、柄を書き入れるにしても非常に便利です。
これはスプリング縫合方式のメリットの一つです。

さて、パラメータにもよりますが、仕上がりは以下のようになります。

クロスモデファイアを使う場合、通常では[クロスフィールドの重み]をデフォルトにしておくと、いい感じに乱れます。
この乱れがリアルな皺を作ったり、縫合を徐々に密なものにしてくれたりしているわけです。
しかし、襟がある場合は少しの乱れでも大きく暴れてしまい、意図した所に収まらなくなります。
許容できないので、[重力]、[全て]、[力]、[空気抵抗]のみ1にして、他は0にします。
その他、[クロス]の[空気抵抗]も0にします。
このように、小さなパーツを含む場合は、気を付けなければならない所が多くなります。

風等の乱れがまったくないため、クロスモデファイアをかけ続けても、変化は少ないです。
縫合もあまりきちっとはされません。
縫合しきれなかった部分が筋となって、地肌が見えてしまっています。
これは手動で縫うか、レンダリング画像を2Dペイントツールで補正すれば良いでしょう。

いかがでしょうか?
複雑さとシンプルさの微妙なバランスに苦心しました。

正直な話、襟の造形のために他の部分を犠牲にしている感があります。
襟を含めて一度で造形するより、襟なしで一旦クロスモデファイアをかけたあとに、改めて襟を作りこんだほうが良いかと思います。

今回の作例では襟のメッシュは以下のようになっています。

この円形の襟の部分を変更すれば別の襟にすることが(理屈上)できます。
とは言え、スプリングによって引っ張られてしまい、完成後の造形予想は難しいものがあります。
特に襟足の高い造形は非常に難しいです。

ワンピースをマリアに適用してみました。
デフォルトのキャラクターと体形が違いすぎて、素直には適用できません。
同じ比率では首が太すぎ、かつ短すぎでBodyに干渉してしまいます。
首が乗っている四角形の外枠の形を変えないよう気を付けながら、ワンピースの首を太く、短くしてBodyと干渉しないように変形させて適用しています。

結局、同じ服をグラマーな大人キャラクター、スレンダーな子供キャラクタ―で共有するのは、色々難しい課題があります。
スレンダーボディに合わせると、必要以上にボディラインが強調された服になってしまいます。
グラマーボディに合わせると、胸が余った服になってしまいます。
結局はキャラクターごとに服をワンメイクで作る必要があるのでしょうか?
それでも縫合スプリングは元のメッシュが単純なため、ターゲットに合わせこむ手数は少なくて済みます。

と、いうことで今回は終わりです。
時間があれば[その10]を書きたいと思います。


挿絵画家になろう(その8)


「挿絵画家になろう(その8)」です。
Blenderのアドオン、MB-Labの啓蒙です。
MB-Labを使って秀逸な少女キャラクターのメッシュオブジェクトを生成し、VRoidStudioの髪をインポートして装着させ、そこそこの服を着せ、キャラクターのマテリアルも弄れるようになり、更に表情も変更できるようになりました。

今回はポーズについてです。
しかしながらMB-LabのキャラクターはBlenderの人型モデルなので単にポーズをつけるだけならばBlenderの操作方法を学べばよいことになります。
ググればポーズのつけかたを解説しているサイトがいくつもあるので今更私が説明する必要もないでしょう。
難しいですが慣れるとわりと自由にポーズを付けられるようになります。

ではあるものの、我らがMB-Labにはポーズライブラリが付属します。
Blenderで人型キャラクターのポーズ付けに挫折した人でもポーズライブラリから選択し、ポーズをつけることができます。
らくちんですね。

ただ決められたポーズだけでは、挿絵を欲する同胞の諸兄姉は満足できないでしょう。
そんな諸兄姉にポーズライブラリを組み合わせて新しいポーズを作成する方法を展開しましょう。
Blenderの知識が要らない代わりにスクリプト言語の知識が必要になってきます。
諸兄姉はPythonの知識がありますよね?
あるといいな。
無くても、今回は言語的な知識はなくても良いように記事を書く予定です。
以前の記事』にPythonのインストールに書いてますので参考にしてください。

MB-LabはBlenderのアドオンなのですが、Windows10の場合、難しい事をしなければ通常以下にインストールされます。

C:\Users\%USERNAME%\AppData\Roaming\Blender Foundation\Blender\2.79\scripts\addons\manuelbastionilab

MB-Labで生成されるキャラクターの雛形は以下のBlender Projectファイルに収められています。

C:\Users\%USERNAME%\AppData\Roaming\Blender Foundation\Blender\2.79\scripts\addons\manuelbastionilab\data
humanoid_library.blend

このファイルを開くと分かるのですが、メッシュやアーマチュア、マテリアル、その他が定義されています。

基本ポーズはAポーズですね。
で、ポーズライブラリは以下のディレクトリになります。

C:\Users\%USERNAME%\AppData\Roaming\Blender Foundation\Blender\2.79\scripts\addons\manuelbastionilab\data\poses

このディレクトリには以下の三つのディレクトリがあります。
female_poses
male_poses
rest_poses

rest_poseのディレクトリには以下のファイルがあります。
a-pose.json
a-pose.json
lambda-pose.json
lambda-pose.json
lambda-pose.json

このファイル名、どこかで見たことがありますね。
そうです、MB-LabのRest Poseの選択肢です。

各ポーズはjson形式というテキストファイルで記述されています。
試しにa-pose.jsonの中身を確認してみましょう。
テキストファイルなので普通にテキストエディッタで開けば見ることができます。
しかし改行がないので若干見にくいので次のようなスクリプトを使って解析します。

import json

pose = './a-pose.json'

with open(pose) as f_b:
    df_b = json.load(f_b)
    for w in df_b:
        print(w," = ",df_b[w])

jsonのファイルはKeyとValueの対を定義するリスト構造となっています。
このスクリプトはKeyとValueの対を表示します。
結果は以下のようになります。

thumb02_L  =  [1.0, 0.0, 0.0, 0.0]
calf_twist_R  =  [1.0, 0.0, 0.0, 0.0]
ring03_L  =  [1.0, 0.0, 0.0, 0.0]
thumb02_R  =  [1.0, 0.0, 0.0, 0.0]
pinky00_L  =  [1.0, 0.0, 0.0, 0.0]
pinky02_R  =  [1.0, 0.0, 0.0, 0.0]
ring00_R  =  [1.0, 0.0, 0.0, 0.0]
breast_L  =  [1.0, 0.0, 0.0, 0.0]
ring02_R  =  [1.0, 0.0, 0.0, 0.0]
lowerarm_R  =  [1.0, 0.0, 0.0, 0.0]
middle02_L  =  [1.0, 0.0, 0.0, 0.0]
neck  =  [1.0, 0.0, 0.0, 0.0]
ring02_L  =  [1.0, 0.0, 0.0, 0.0]
middle03_L  =  [1.0, 0.0, 0.0, 0.0]
ring00_L  =  [1.0, 0.0, 0.0, 0.0]
pelvis  =  [1.0, 0.0, 0.0, 0.0]
ring01_R  =  [1.0, 0.0, 0.0, 0.0]
thigh_R  =  [1.0, 0.0, 0.0, 0.0]
index02_R  =  [1.0, 0.0, 0.0, 0.0]
upperarm_L  =  [1.0, 0.0, 0.0, 0.0]
clavicle_R  =  [1.0, 0.0, 0.0, 0.0]
pinky02_L  =  [1.0, 0.0, 0.0, 0.0]
index01_R  =  [1.0, 0.0, 0.0, 0.0]
middle00_L  =  [1.0, 0.0, 0.0, 0.0]
calf_twist_L  =  [1.0, 0.0, 0.0, 0.0]
thigh_twist_L  =  [1.0, 0.0, 0.0, 0.0]
upperarm_twist_L  =  [1.0, 0.0, 0.0, 0.0]
middle02_R  =  [1.0, 0.0, 0.0, 0.0]
hand_R  =  [1.0, 0.0, 0.0, 0.0]
ring01_L  =  [1.0, 0.0, 0.0, 0.0]
toes_R  =  [1.0, 0.0, 0.0, 0.0]
index03_R  =  [1.0, 0.0, 0.0, 0.0]
lowerarm_L  =  [1.0, 0.0, 0.0, 0.0]
spine03  =  [1.0, 0.0, 0.0, 0.0]
lowerarm_twist_L  =  [1.0, 0.0, 0.0, 0.0]
middle01_R  =  [1.0, 0.0, 0.0, 0.0]
index00_R  =  [1.0, 0.0, 0.0, 0.0]
spine01  =  [1.0, 0.0, 0.0, 0.0]
foot_L  =  [1.0, 0.0, 0.0, 0.0]
index02_L  =  [1.0, 0.0, 0.0, 0.0]
thumb01_R  =  [1.0, 0.0, 0.0, 0.0]
pinky03_L  =  [1.0, 0.0, 0.0, 0.0]
ring03_R  =  [1.0, 0.0, 0.0, 0.0]
thumb03_R  =  [1.0, 0.0, 0.0, 0.0]
index01_L  =  [1.0, 0.0, 0.0, 0.0]
middle00_R  =  [1.0, 0.0, 0.0, 0.0]
lowerarm_twist_R  =  [1.0, 0.0, 0.0, 0.0]
breast_R  =  [1.0, 0.0, 0.0, 0.0]
foot_R  =  [1.0, 0.0, 0.0, 0.0]
middle01_L  =  [1.0, 0.0, 0.0, 0.0]
upperarm_R  =  [1.0, 0.0, 0.0, 0.0]
pinky01_R  =  [1.0, 0.0, 0.0, 0.0]
middle03_R  =  [1.0, 0.0, 0.0, 0.0]
hand_L  =  [1.0, 0.0, 0.0, 0.0]
pinky01_L  =  [1.0, 0.0, 0.0, 0.0]
head  =  [1.0, 0.0, 0.0, 0.0]
spine02  =  [1.0, 0.0, 0.0, 0.0]
calf_R  =  [1.0, 0.0, 0.0, 0.0]
thigh_L  =  [1.0, 0.0, 0.0, 0.0]
clavicle_L  =  [1.0, 0.0, 0.0, 0.0]
upperarm_twist_R  =  [1.0, 0.0, 0.0, 0.0]
index03_L  =  [1.0, 0.0, 0.0, 0.0]
thumb03_L  =  [1.0, 0.0, 0.0, 0.0]
calf_L  =  [1.0, 0.0, 0.0, 0.0]
root  =  [1.0, 0.0, 0.0, 0.0]
toes_L  =  [1.0, 0.0, 0.0, 0.0]
pinky03_R  =  [1.0, 0.0, 0.0, 0.0]
pinky00_R  =  [1.0, 0.0, 0.0, 0.0]
index00_L  =  [1.0, 0.0, 0.0, 0.0]
thumb01_L  =  [1.0, 0.0, 0.0, 0.0]
thigh_twist_R  =  [1.0, 0.0, 0.0, 0.0]

ポーズデーターファイルはボーンとその回転量を表す四つの実数の組のリストデーターなのです。
対応するボーンは以下のように実際に使われているアーマチュアのボーン名と一致します。

ボーンは親のボーンがあって子のボーンは親の位置と回転量に影響をうけます。
親子関係のツリー構造は以下のようになっています。

root:すべてのボーンの親
└pelvis:腰
  ├thigh_R:太腿
  │├thigh_twist_R
  │└calf_R:脛
  │  ├calf_twist_R
  │  └foot_R:足の甲
  │    └toes_R:爪先
  ├thigh_L:太腿
  │├thigh_twist_L
  │└calf_L:脛
  │  ├calf_twist_L
  │  └foot_L:足の甲
  │    └toes_L:爪先
  └spine01:脊椎
    └spine02
      └pine03
        ├neck:首
        │└head:頭
        ├breast_R:乳房
        ├breast_L:乳房
        ├clavicle_R:鎖骨
        │└upperarm_R:上腕
        │  ├upperarm_twist_R
        │  └lowerarm_R:下腕
        │    ├lowerarm_twist_R
        │    └hand_R:手首
        │     ├thumb01_R:親指
        │     │└thumb02_R
        │     │  └thumb03_R
        │     ├index00_R:人差し指
        │     │└index01_R
        │     │  └index02_R
        │     │    └index03_R
        │     ├middle00_R:中指
        │     │└middle01_R
        │     │  └middle02_R
        │     │    └middle03_R
        │     ├ring00_R:薬指
        │     │└ring01_R
        │     │  └ring02_R
        │     │    └ring03_R
        │     └pinky00_R:小指
        │       └pinky01_R
        │         └pinky02_R
        │           └pinky03_R
        └clavicle_L:鎖骨
          └upperarm_L:上腕
            ├upperarm_twist_L
            └lowerarm_L:下腕
              ├lowerarm_twist_L
              └hand_L:手首
                ├thumb01_L:親指
                │└thumb02_L
                │  └thumb03_L
                ├index00_L:人差し指
                │└index01_L
                │  └index02_L
                │    └index03_L
                ├middle00_L:中指
                │└middle01_L
                │  └middle02_L
                │    └middle03_L
                ├ring00_L:薬指
                │└ring01_L
                │  └ring02_L
                │    └ring03_L
                └pinky00_L:小指
                  └pinky01_L
                    └pinky02_L
                      └pinky03_L

面白いことに 親の位置と回転量に影響をうけるものの、子の相対的な回転は子自身の回転量によってのみ決まります。
つまり、肩の位置がどれだけ変わろうが、腕の回転量は影響を受けないということです。

ボーンの回転量はQuaternionという形式の四つの実数のリストによって表現されます。
Quaternion が何であるのかはさておいて、回転を意味する以上はどのポジションからの回転かが重要です。
答えを言えばa-poseを基準とする回転です。
なので、a-pose.jsonはすべての要素が[1.0, 0.0, 0.0, 0.0]、回転なしと定義されています。

さて、ここからが本題なのですが Quaternion で表現する任意の二つの回転量は球面線形補間ができるのです。
つまり二つのポーズの中間のポーズを計算によって求めることができてしまうのです。
実際にやってみましょう。

次のスクリプトをpose_slerp.pyとして保存してください。
スクリプトの意味を理解する必要はとりあえずはありません。

import sys
import json
import numpy
from pyquaternion import Quaternion

if __name__ == '__main__':
    args = sys.argv
    if 2 <= len(args):
        base_pose = args[1]
    else:
        print("no base pose!")
        exit()
    if 3 <= len(args):
        reference_pose = args[2]
    else:
        print("no reference_pose!")
        exit()
    if 4 <= len(args):
        amount = args[3]
    else:
        print("no amount!",args[3])
        exit()
    if 5 <= len(args):
        out_pose = args[4]
    else:
        out_pose = './output.json'

with open(base_pose) as f_b:
    print("Base pose",base_pose, "is loaded")
    df_b = json.load(f_b)

with open(reference_pose) as f_r:
    print("Reference pose",reference_pose, "is loaded")
    df_r = json.load(f_r)

for w in df_b:
    q1 = Quaternion(df_b[w])
    q2 = Quaternion(df_r[w])
    q3 = Quaternion.slerp(q1, q2, float(amount))
    df_b[w] = q3.elements.tolist()

f_out = open(out_pose, 'w')
f_out.write(json.dumps(df_b))
print("Output pose file is",out_pose)

pyquaternionというモジュールが必要です。
以下のようにしてインストールしてください。

python -m pip install pyquaternion

同じディレクトリに以下のポーズライブラリファイルを保存します。
 a-pose.json
 shojo_classic01.json

コマンドラインから以下を実行します。

python pose_slerp.py a-pose.json shojo_classic01.json 0.50 output.json

コマンドの意味は以下です。
python <実行スクリプト名> <ベースポーズファイル名> <ターゲットポーズファイル名> <補間の割合> <出力ポーズファイル名>

<補間の割合>は0~1の実数を指定してください。
0.5でちょうど中間の補間となります。

output.jsonという新しいポーズファイルができるので、MB-Labのポーズとしてloadすれば、生成したポーズを読み込むことができます。
次のアニメーションは0.00~1.00まで0.05刻みで変化させ、一枚ずつMB-Labに読み込ませたものです。

いかがでしょうか?
任意の二つのポーズから、二つのポーズを補完する新しいポーズを生成できるのです。
MB-Labにはたくさんの魅力的なポーズが用意されています。
※ただしfemaleに限る
更に新しく作ったポーズと別のポーズを組み合わせることも可能。
つまり組み合わせは無限。
「あのポーズとこのポーズを組み合わせれば」と夢が膨らむと思いませんか?

とはいえ、これでも自作小説に挿絵を欲する諸兄姉には満足いただけないかもしれません。
「ポーズは分かった。でも手が思うようにポージングできない」
「手指のボーンって、なにげに全体の半分以上あって収取つかないんですけれど」
そう思われるでしょう。

ごもっともです。
体のポーズに引きずられて、手を思うように変形させることができません。
手のポーズが思い通りにならないのは困ります。
手は口ほどにものをいうのですから。
指差し、ピース、サムアップ、ブーイング、グー、チョキ、パー。
フレミングの左手の法則。
シーンに応じて手のポーズを付けなければなりませんよね?

大丈夫です。
ソリューションを用意してあります。
Quaternion では部分の差し替えができるのです。
任意のポーズの任意のボーンだけの回転量を移植できるのです。
手はHand_R,Hand_Lを親とする一連のボーンツリーで構成されています。
よって他のポーズファイルの手の構成を移植することができます。
実際にやってみましょう。

次のスクリプトをpose_copy_hands.pyとして保存してください。
スクリプトの意味を理解する必要はとりあえずはありません。
ただすごくベタなスクリプトなので逆になにをやっているかは想像できると思います。

import sys
import json

if __name__ == '__main__':
    args = sys.argv
    if 2 <= len(args):
        base_pose = args[1]
    else:
        print("no base pose!")
        exit()
    if 3 <= len(args):
        reference_pose = args[2]
    else:
        print("no reference_pose!")
        exit()
    if 4 <= len(args):
        out_pose = args[3]
    else:
        out_pose = './output.json'

with open(base_pose) as f_b:
    print("Base pose",base_pose, "is loaded")
    df_b = json.load(f_b)

with open(reference_pose) as f_r:
    print("Reference pose",reference_pose, "is loaded")
    df_r = json.load(f_r)

df_b['hand_R']      = df_r['hand_R']      
df_b['thumb01_R']   = df_r['thumb01_R']   
df_b['thumb02_R']   = df_r['thumb02_R']   
df_b['thumb03_R']   = df_r['thumb03_R']   
df_b['index00_R']   = df_r['index00_R']   
df_b['index01_R']   = df_r['index01_R']   
df_b['index02_R']   = df_r['index02_R']   
df_b['index03_R']   = df_r['index03_R']   
df_b['middle00_R']  = df_r['middle00_R']  
df_b['middle01_R']  = df_r['middle01_R']  
df_b['middle02_R']  = df_r['middle02_R']  
df_b['middle03_R']  = df_r['middle03_R']  
df_b['ring00_R']    = df_r['ring00_R']    
df_b['ring01_R']    = df_r['ring01_R']    
df_b['ring02_R']    = df_r['ring02_R']    
df_b['ring03_R']    = df_r['ring03_R']    
df_b['pinky00_R']   = df_r['pinky00_R']   
df_b['pinky01_R']   = df_r['pinky01_R']   
df_b['pinky02_R']   = df_r['pinky02_R']   
df_b['pinky03_R']   = df_r['pinky03_R']   

df_b['hand_L']      = df_r['hand_L']      
df_b['thumb01_L']   = df_r['thumb01_L']   
df_b['thumb02_L']   = df_r['thumb02_L']   
df_b['thumb03_L']   = df_r['thumb03_L']   
df_b['index00_L']   = df_r['index00_L']   
df_b['index01_L']   = df_r['index01_L']   
df_b['index02_L']   = df_r['index02_L']   
df_b['index03_L']   = df_r['index03_L']   
df_b['middle00_L']  = df_r['middle00_L']  
df_b['middle01_L']  = df_r['middle01_L']  
df_b['middle02_L']  = df_r['middle02_L']  
df_b['middle03_L']  = df_r['middle03_L']  
df_b['ring00_L']    = df_r['ring00_L']    
df_b['ring01_L']    = df_r['ring01_L']    
df_b['ring02_L']    = df_r['ring02_L']    
df_b['ring03_L']    = df_r['ring03_L']    
df_b['pinky00_L']   = df_r['pinky00_L']   
df_b['pinky01_L']   = df_r['pinky01_L']   
df_b['pinky02_L']   = df_r['pinky02_L']   
df_b['pinky03_L']   = df_r['pinky03_L']   

f_out = open('out_pose', 'w')
f_out.write(json.dumps(df_b))

コマンドラインから以下を実行します。

python pose_copy_hands.py a-pose.json shojo_classic01.json output.json

コマンドの意味は以下です。
python <実行スクリプト名> <ベースポーズファイル名> <手のポーズを取り込むポーズファイル名> <出力ポーズファイル名>

出力結果ファイル output.json を MB-Labの少女キャラクターに読み込むと以下のようになります。

a-poseにshojo_classic01の手のポーズが移植されました。
つまり体のポーズを仕上げたあと、手のポーズだけを目的のポーズに差し替えることができるのです。
スクリプトを改造すれば右手だけ、もしくは左手だけ、もしくは人差し指だけというように任意の部位を差し替えることができるので応用が利きます。

ついでに右手のポーズを左手に移植、またはその逆を行う例を紹介しましょう。
次のスクリプトをpose_copy_hand_one2other.pyとして保存してください。
スクリプトの意味を理解する必要はとりあえずはありません。
ただこのスクリプトもベタです。
諸兄姉は何を行っているのか推測できるでしょう。

import sys
import json

if __name__ == '__main__':
    args = sys.argv
    if 2 <= len(args):
        base_pose = args[1]
    else:
        print("no base pose!")
        exit()
    if 3 <= len(args):
        print(args[2])
        if ((args[2] != 'l2r') and (args[2] != 'r2l')):
            print("sub-command must be l2r or r2l") 
            exit()

    if 4 <= len(args):
        out_pose = args[3]
    else:
        out_pose = './output.json'

def x_axis_mirrord(a):
    b = a[:]
    b[2] *= -1.0
    b[3] *= -1.0
    return(b[:])

with open(base_pose) as f:
    print("Base pose",base_pose, "is loaded")
    df = json.load(f)

if (args[2] == 'l2r'):
    df['hand_R']     = x_axis_mirrord(df['hand_L'])
    df['thumb01_R']  = x_axis_mirrord(df['thumb01_L'])
    df['thumb02_R']  = x_axis_mirrord(df['thumb02_L'])
    df['thumb03_R']  = x_axis_mirrord(df['thumb03_L'])
    df['index00_R']  = x_axis_mirrord(df['index00_L'])
    df['index01_R']  = x_axis_mirrord(df['index01_L'])
    df['index02_R']  = x_axis_mirrord(df['index02_L'])
    df['index03_R']  = x_axis_mirrord(df['index03_L'])
    df['middle00_R'] = x_axis_mirrord(df['middle00_L'])
    df['middle01_R'] = x_axis_mirrord(df['middle01_L'])
    df['middle02_R'] = x_axis_mirrord(df['middle02_L'])
    df['middle03_R'] = x_axis_mirrord(df['middle03_L'])
    df['ring00_R']   = x_axis_mirrord(df['ring00_L'])
    df['ring01_R']   = x_axis_mirrord(df['ring01_L'])
    df['ring02_R']   = x_axis_mirrord(df['ring02_L'])
    df['ring03_R']   = x_axis_mirrord(df['ring03_L'])
    df['pinky00_R']  = x_axis_mirrord(df['pinky00_L'])
    df['pinky01_R']  = x_axis_mirrord(df['pinky01_L'])
    df['pinky02_R']  = x_axis_mirrord(df['pinky02_L'])
    df['pinky03_R']  = x_axis_mirrord(df['pinky03_L'])
else :
    df['hand_L']     = x_axis_mirrord(df['hand_R'])
    df['thumb01_L']  = x_axis_mirrord(df['thumb01_R'])
    df['thumb02_L']  = x_axis_mirrord(df['thumb02_R'])
    df['thumb03_L']  = x_axis_mirrord(df['thumb03_R'])
    df['index00_L']  = x_axis_mirrord(df['index00_R'])
    df['index01_L']  = x_axis_mirrord(df['index01_R'])
    df['index02_L']  = x_axis_mirrord(df['index02_R'])
    df['index03_L']  = x_axis_mirrord(df['index03_R'])
    df['middle00_L'] = x_axis_mirrord(df['middle00_R'])
    df['middle01_L'] = x_axis_mirrord(df['middle01_R'])
    df['middle02_L'] = x_axis_mirrord(df['middle02_R'])
    df['middle03_L'] = x_axis_mirrord(df['middle03_R'])
    df['ring00_L']   = x_axis_mirrord(df['ring00_R'])
    df['ring01_L']   = x_axis_mirrord(df['ring01_R'])
    df['ring02_L']   = x_axis_mirrord(df['ring02_R'])
    df['ring03_L']   = x_axis_mirrord(df['ring03_R'])
    df['pinky00_L']  = x_axis_mirrord(df['pinky00_R'])
    df['pinky01_L']  = x_axis_mirrord(df['pinky01_R'])
    df['pinky02_L']  = x_axis_mirrord(df['pinky02_R'])
    df['pinky03_L']  = x_axis_mirrord(df['pinky03_R'])

f_out = open(out_pose, 'w')
f_out.write(json.dumps(df))
print("Output file is",out_pose)

コマンドラインから以下を実行します。

python pose_copy_hand_one2other.py output.json l2r output2.json

これは上で生成したoutput.jsonを入力に左手のポーズを右手にコピーし、output2.jsonとしてポーズファイルを生成します。
MB-Labの少女キャラクターにoutput2.jsonを読み込んでみましょう。

手にご注目ください。
左手のポーズが右手に移植されていることが分かります。
同様に以下を実行してください。

python pose_copy_hand_one2other.py output.json r2l output3.json

これは上で生成したoutput.jsonを入力に右手のポーズを左手にコピーし、output3.jsonとしてポーズファイルを生成します。
output3.jsonを読み込んでみましょう。

期待通りの結果となっています。
いかがでしょうか?
まったくキャラクターのポーズ編集なしで、かなり思い通りのポーズをとらせることができることをご理解いただけましたでしょうか?
後は自分なりのポーズライブラリを蓄積してゆけばよいわけです。
無論Blenderでのポーズ編集ができるようになればもっと自由度が増すでしょう。
微調整を行うのはそれほど難しいことではないので、どんどんとチャレンジしてください。

今回の記事はMB-Labの説明ではないばかりか、Blenderの機能ですらありませんでした。
MB-Labのデーターファイルはどれも取り扱いやすいjson形式となっています。
だからスクリプトで変化させることができてしまうのです。

実際にデーターファイルを弄るためにはスクリプト言語の知識が必要だったりしますので、その実ポーズの編集を覚えるのとどちらが早いかは微妙なところもあります。
しかし、苦労したポーズは取っておいて、ライブラリ化すると良いと思います。

今回はこれで終わりです。
時間があれば[その9]を書きたいと思います。



挿絵画家になろう(その7)


「挿絵画家になろう(その7)」です。
Blenderのアドオン、MB-Labの啓蒙です。
前回までで、MB-Labを使って少女キャラクターを生成し、VRoidStudioの髪をインポートして装着させ、そこそこの服を着せ、キャラクターのマテリアルも弄れるようになり、更に表情も変更できるようになりました。
今回もMB-Labの使い方に関して説明を試みたいと思います。
今回は表情の変更の続きです。

前回、MB-Labで表情を変更する方法にMB-Labが用意する[FACE EXPRESSIONS]を使う方法とシェイプキーを直接変更する方法があることを述べました。
[FACE EXPRESSIONS]は複数のシェイプキーのセットを持っていて、シェイプキーを同時に変化させる機能です。
表情は目や口、頬、眉などの組み合わせで表現されます。
MB-Labの考え方として、シェイプキーで個々のパーツの変化を用意し、シェイプキーの組み合わせを [FACE EXPRESSIONS] で用意してセットで変更できるようにしているわけです。

[FACE EXPRESSIONS] で用意されている表情で事足りるのならば [FACE EXPRESSIONS] のみを使うことが簡便です。
しかし [FACE EXPRESSIONS] で満足できない場合は、次の手段としてシェイプキー単体を変更すれば良いわけです。
勿論、シェイプキーは抽象度が下がるわけですから必要な組み合わせを自分で決めて全てコントロールする必要があります。
しかし抽象度が低いということは自由度が高いということなのでよりきめ細かい表情を作ることができます。

シェイプキーはプロパティウインドウのオブジェクトデータ(逆三角形のマーク)から見ることができます。
girl1_bodyのオブジェクトが選択されていることを確認してから、編集モードに切り替えます。
プロパティウインドウのオブジェクトデータ を選択し、[シェイプキー]の項目を見てください。
たくさんのシェイプキーが用意されていることが分かります。

シェイプキーのリストの下に[シェイプキーを編集モードで表示(メッシュのみ)]というボタンがあるので押下します。
これを押すとメッシュの変更ができなくなる代わりに、選択したシェイプキーのメッシュ変化を見ることができます。
前部のシェイプキーの変化をアニメーションにしてみました。

かなり細かい変化に関して作りこまれていることがわかります。
これらを組み合わせれば微妙な表情も表現できるのではないでしょうか?
尚シェイプキーは表情にだけ使うものではありません。
呼吸による胸の上下や嚥下による喉の変化など、細かい演出に用いられると思われるものも用意されています。

これでほぼ表情の作成は問題なくなったといえます。
凄いですねMB-Lab。
口を大きく開けた場合での歯が気になりますが、私たちの目的は小説の挿絵です。
それほど口を大きく開けたシーンは必要ないと思われますのであまり問題にはならないのではないでしょうか?

とはいえ、どうしてもなんとかしたい場合はシェイプキーのメッシュを弄ってしまえば解決はします。
実際にやってみましょう。

先ずは邪魔な髪と服を不可視にします。
オブジェクトモードにしてSendagaya_Shino_Hairを右クリックで選択し、3Dビューのプレーンにマウスカーソルを置いて[h]キーを押すと髪が不可視状態になります。

同様にOnepiece_Placeを選択し[h]キーで拭くを不可視にします。

girl1_bodyを選択して編集しやすいようにズームします。

編集モードに切り替えます。
[3Dビューのシェーディング]はソリッドにします。
プロパティウインドウのオブジェクトデータ を選択し、[シェイプキー]の項目のリストから[Basis]を選択してください。

シェイプキーのリストの下、[シェイプキーを編集モードで表示(メッシュのみ)]というボタンが解除されていることを確認します。

顔の上にマウスカーソルを当てて[a]キーを何回か押し、何も選択されていない状態にしてください。

顔の額あたりにマウスカーソルを当てて、[l]キーを押すと顔のメッシュが選択されます。
今回は歯のメッシュを弄るので顔は邪魔なので不可視化する意図です。

[h]キーを押下すると顔の表面が不可視になり顔の中身が剥き出しになります。

あとは目的の歯や歯茎のメッシュを編集すれば良いことになります。
注意しなければならないのは頂点の位置は変えても良いのですが、メッシュのトポロジー(頂点同士の繋がり)は変えるべきではないということです。
特に頂点を増やしたり減らしたりするとシェイプキーが意図しない変化となります。
またUVマップとの相関がとれなくなることも避けなければなりません。

編集しやすいように歯をズームします。

上の図の3Dカーソルがあるあたり(上下の歯の合わせ目左にある赤と白の丸)を[alt]キーを押しながら右クリックします。


上の歯の歯並びの選択が選択されます。

メッシュの操作ですが、Z方向(上下方向)のみの変更にとどめます。
理由は他の方向に動かすと収拾がつかなくなるからです。
変化量もキーボードで[↑]キー、[↓]キーの回数で管理し、必要最小限の変化になるよう管理します。
では実際にメッシュを弄ります。

マウスカーソルを歯茎に合わせた状態で[g]、[z]の順番でキー押下します。
選択頂点の上下移動となりますので[↑]キーを5回程度押して移動させます。
[enter]キーを押すと移動が確定します。

今度は範囲を広げます。
[ctrl]キーを押しながらテンキーの[+]キーを押します。
選択範囲が広がります。

マウスカーソルを歯茎に合わせた状態で[g]、[z]の順番でキー押下します。
選択頂点の上下移動となりますので[↑]キーを12回程度押して移動させます。
[enter]キーで移動が確定します。

同様の手順を繰り返し、上の歯を短くしてゆきます。

下の歯の歯並びの最上段が見えてきました。
下の歯の最上段のエッジを[alt]を押しながら右クリックして選択します。

下の歯は臼歯の上部が平たいので範囲を広げます。
[ctrl]キーを押しながらテンキーの[+]キーを押します。

マウスカーソルを歯茎に合わせた状態で[g]、[z]の順番でキー押下します。
選択頂点の上下移動となりますので[↓]キーを12回程度押して移動させます。
[enter]キーで移動が確定します。

同様にして範囲を広げ、歯を短くしてゆきます。

奥歯のエッジが残っているので選択します。

[g]キー、[z]キーを順番に押し、[↓]キーで見えなくなるまで下げます。

どこまで拘るのかによりますが、これまでの操作で歯を喰いしばる系以外のシェイプキーは歯の影響が緩和されることになります。
すこし見てみましょう。
不可視にしたメッシュやオブジェクトは[alt]+[h]で可視化させることができます。

Expressions_mouthOpenLarge_maxを0.5にした表情です。
歯が目立たなくなっています。

歯を喰いしばる系のシェイプキーは明らかに意図的に歯を強調しているものです。
アニメ的な表情表現では「い」行の発音の時に使うくらいでその他ではあまり用途がないでしょう。

上はExpressions_mouthSmileOpen_maxを0.5にした表情です。
シーンによっては使えるかもしれません。

アニメ的な表現では歯、特に下の歯は無い方が良いかもしれません。
そのような場合は設定するマテリアルを透明にすると実現できます。
下の歯だけを透明にするのは下の歯だけを頂点選択してマテリアルを設定します。

透明化の例として下睫毛を見えなくする方法を紹介しましょう。
アニメ的な表情表現では上睫毛は濃い色にして目の輪郭をはっきりさせ、下睫毛は省略して柔らかな表情になることを期待することが多いと思います。
しかしMB-Labでは眉毛、上睫毛、下睫毛がセットになっています。
下睫毛だけを透明化させます。

編集モードに切り替えます。
[3Dビューのシェーディング]はソリッドにします。
顔の上にマウスカーソルを当てて[a]キーを何回か押し、何も選択されていない状態にしてください。

右目の下睫毛にカーソルを当てて[l]キーを押します。
右の睫毛が選択されます。

同様に左目の下睫毛にカーソルを当てて[l]キーを押します。

右の睫両目の下睫毛が選択されました。

プロパティシェルフの[マテリアル]を選択します。

マテリアルスロットの右にある[+]ボタンをクリックして新しいマテリアルスロットを作成します。

マテリアルスロットの右にある[△]ボタンで新しいマテリアルスロットを一番上まで持ち上げます。

マテリアルの選択のセレクタにある[+]ボタンをクリックして新しいマテリアルを作成します。

[サーフェス]の項のセレクタから[透過BSDF]を選択します。

[サーフェス]の項、[カラー]の色部分をクリックするとカラーサークルが現れるので、完全な白にします。

割り当てをクリックして確定させます。

これで下睫毛に透明なマテリアルが設定されました。

いかがでしょうか?
下睫毛が消えたことによりかなり柔らかい表情になったことと思われます。

ポーズと表情をつけてレンダリングしてみました。

今回の記事はMB-Labの説明というよりはMB-Labで生成したキャラクターをBlenderの機能でどう弄るかの説明でした。
このようにMB-Labで生成したキャラクターは自由に弄ることができます。

ここまでMB-Labについて説明してきましたが、いかに素晴らしいものであるかお伝えできたでしょうか?
MB-Labはまだまだたくさんの機能がありますが、正直私は良く分かっていません。
しかし、ここまでの知識でだいたいのことはできると思います。
この一連の記事をご覧になって自作小説の挿絵を描かれる方が現れると幸甚です。

今回はこれで終わりです。
MB-Labを主題にするのは今回が最後だと思います。
時間があれば[その8]を書きたいと思います。