Blenderのシェーダーお絵かき


今回は完全に自分用のメモです。
Twitterを見ていて、Blenderのシェーダーノードでお絵かきしている方がいらっしゃったので追実験。

Blender 2.79bしか使えないのでノードは自作です。

なお、twの元ネタは以下であるようです。
楽しい!Unityシェーダー お絵描き入門!

Blenderで平面ポリゴンを追加して、その平面にシェーダーノードで図形を描写します。
凄く面白いアイデアであると思います。

構造は意外と簡単です。

オブジェクトのテクスチャ画像からx,y各座標を取り出し、中央からの距離と角度を分離します。
そして距離と角度を入力パラメータとする関数を作成し て濃度グラフを作成します。
濃度にカラーランプノード等で閾値の範囲を決め、シェーダーで描写します。
等高線を取り出すノリですね。

fract, distance, angleの三つの ノードグループを作っています。
取り出すベクトルがレングス1.0に正規化されている前提としています。

fractは入力をオブジェクトのテクスチャ座標ベクトルとします。
各xyが周期1、レンジ-1.0~1.0の信号であると仮定し、任意倍数に逓倍し、新しいxy座標を個別に出力します。
出力の範囲は-1.0~1.0の実数です。

\(Fract(x,a) = mod(x+1.0 , \frac{2}{a})・\frac{a}{2} – 0.5\\
Fract(y,a) = mod(y+1.0 , \frac{2}{a})・ \frac{a}{2} – 0.5\)

distanceは各xy座標を値として受け取り、原点からの距離を求めます。
出力の範囲は0.0~ \(\sqrt{2}\) の実数です

\(Distance(x,y)=\sqrt{x^2+y^2}\)

グループノードと出力をそのまま画像出力した例を以下に示します。

原点がゼロで値がゼロ、離れるに従い線形に値が増加してゆきます。
同じ距離であれば同じ値になります。
色表現的な意味では四隅は飽和していることに注意が必要です。

distanceを用いれば数式により同心円系の図形が描けます。

\(Func(s) = abs(sin(16πs))\)

angleは 各xy座標を値として受け取り、 原点との角度を計算します。
出力の範囲は \( 0.0~2π \)です。

\(Angle(x,y)=\\
 cos^{-1}(\frac{x}{\sqrt{x^2+y^2} }) (if y ≧ 0)\\
Angle(x,y)=\\
 cos^{-1}(\frac{-x}{\sqrt{x^2+y^2} })+π (if y < 0)\)

グループノードと出力を \( 2π \)で除して画像出力した例を以下に示します。

同じ角度であれば同じ値になり、反時計回りに値が増加してゆきます。

後はもう一つのノードグループfunc1に適当な関数を記述すれば良いわけです。

\(func1(s)=abs(cos(2.5s))\)

関数を設定してカラーランプノードを弄れば、抜きの入った集中線も実現できます。

\(func1(s)=abs(cos(100s))\)

桜の花びら。

\(Func2(s) = min(\\
  abs(cos(2.5x))+0.4 ,\\
  abs(sin(2.5x))+1.1)・0.240\)

この作例ではDistance系とAngle系は乗算ではなく加算しています。

fractノードの入力を変えることにより任意の縮小繰り返しができます。

数式により任意の図形を作成し、それを繰り返しパターンにできるのです。

シェーダーノードはプログラム環境として機能し、様々な図形を描画できるところがとても興味深いです。

参考までにblenderファイルを置いておきます。
shader_node_sample.blend


挿絵画家になろう(その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]を書きたいと思います。


ツールの話をしよう~コマンドライン翻訳


このブログを見てらっしゃる方はtwitterのFFの方がメインであろうかと思います。
つまりは小説関連のご同胞ですよね?
皆さん、翻訳・辞書ツールを使っていらっしゃると思います。
今回は私が使っている Windows10 PC上でのコマンドラインで動作する翻訳・辞書ツールをご紹介しようと思います。

その名もtranslate-shellです。
soimort/translate-shell: Command-line translator … – GitHub

このツールはコマンドラインからgoogle翻訳等のWEBアプリを使って、翻訳したり辞書をひいたりしてくれる超便利なソフトです。
小説の執筆をしているときに、ちょっと「この英単語、どういう意味だっけ?」とか、「英語タイトルなんにしよう?」とか思うことありますよね。
それでいちいちChromeを立ち上げてgoogle翻訳を開くってめんどくさいですよね?
そんなとき、コマンドラインからバシャバシャっと入力して辞書を引いたり翻訳できたら便利だと思いません?
私はすごく思います。

例えば和英翻訳ならばこんな感じ。

kuyo@DESKTOP-8O0L9BP:~$ je '腹が減った'
腹が減った
(Haragahetta)

I am hungry

Translations of 腹が減った
[ 日本語 -> English ]

腹が減った
    I am hungry, hungry
kuyo@DESKTOP-8O0L9BP:~$

例えば英和翻訳ならばこんな感じ。

kuyo@DESKTOP-8O0L9BP:~$ ej 'Never let me go'
Never let me go

私を離さないで
(Watashi o hanasanaide)

Translations of Never let me go
[ English -> 日本語 ]

Never let me go
    私を離さないで, 私を手放すことはありません, 私は手放すことはありません
kuyo@DESKTOP-8O0L9BP:~$

例えば和英辞書ならばこんな感じ。

kuyo@DESKTOP-8O0L9BP:~$ je -d 'きょうだい'
きょうだい
(Kyō dai)

Siblings

Translations of きょうだい
[ 日本語 -> English ]
kuyo@DESKTOP-8O0L9BP:~$

例えば英和辞書ならこんな感じ。

kuyo@DESKTOP-8O0L9BP:~$ ej 'Sibling'
Sibling
/ˈsibliNG/

兄弟姉妹
(Keiteishimai)

Translations of Sibling
[ English -> 日本語 ]

Sibling
    兄弟姉妹, 兄弟
kuyo@DESKTOP-8O0L9BP:~$

英英辞書的にも使えます。

kuyo@DESKTOP-8O0L9BP:~$ ej -d 'love'
love
/ləv/

愛
(Ai)

Definitions of love
[ English -> 日本語 ]

verb
    feel a deep romantic or sexual attachment to (someone).
        - "Though you tried to deny it, you must trust your heart that deep inside you love him."
    Synonyms: care very much for, feel deep affection for, hold very dear, adore, think the world of, be devoted to, dote on, idolize, worship, be in love with, be infatuated with, be smitten with, be besotted with, be mad/crazy/nuts/wild about, have a crush on, carry a torch for

noun
    an intense feeling of deep affection.
        - "My brother, and his real, strong love for me that was able to pull me back into the world I know."
    Synonyms: deep affection, fondness, tenderness, warmth, intimacy, attachment, endearment, devotion, adoration, doting, idolization, worship, passion, ardor, desire, lust, yearning, infatuation, besottedness

    a person or thing that one loves.
        - "By the end of the trip I knew she had two loves ; her son and her carpets."
    Synonyms: beloved, loved one, love of one's life, dear, dearest, dear one, darling, sweetheart, sweet, angel, honey, lover, inamorato, inamorata, amour, paramour

    (in tennis, squash, and some other sports) a score of zero; nil.
        - "To come back from two sets to love and win it is an awesome feeling."

Synonyms
    verb
        - care very much for, feel deep affection for, hold very dear, adore, think the world of, be devoted to, dote on, idolize, worship, be in love with, be infatuated with, be smitten with, be besotted with, be mad/crazy/nuts/wild about, have a crush on, carry a torch for
        - like very much, delight in, enjoy greatly, have a passion for, take great pleasure in, derive great pleasure from, relish, savor, have a weakness for, be partial to, have a soft spot for, have a taste for, be taken with, get a kick out of, have a thing about, be mad/crazy/nuts/wild about, be hooked on, get off on
        - enjoy
        - have intercourse, eff, hump, get laid, make out, have sex, do it, fuck, bed, make love, jazz, sleep together, bang, screw, bonk, be intimate, know, lie with, have it off, sleep with

    noun
        - relationship, love affair, romance, liaison, affair of the heart, amour
        - beloved, loved one, love of one's life, dear, dearest, dear one, darling, sweetheart, sweet, angel, honey, lover, inamorato, inamorata, amour, paramour
        - best wishes, regards, good wishes, greetings, kind/kindest regards
        - liking of/for, enjoyment of, appreciation of/for, taste for, delight for/in, relish of, passion for, zeal for, appetite for, zest for, enthusiasm for, keenness for, fondness for, soft spot for, weakness for, bent for, proclivity for, inclination for, disposition for, partiality for, predilection for, penchant for
        - compassion, care, caring, regard, solicitude, concern, friendliness, friendship, kindness, charity, goodwill, sympathy, kindliness, altruism, unselfishness, philanthropy, benevolence, fellow feeling, humanity
        - deep affection, fondness, tenderness, warmth, intimacy, attachment, endearment, devotion, adoration, doting, idolization, worship, passion, ardor, desire, lust, yearning, infatuation, besottedness
        - love life, lovemaking, making love, sexual love
        - passion
        - dear, dearest, beloved, honey
        - sexual love

Examples
    - In short, how can there be love for the country without love for the people?

    - they were both in love with her

    - babies fill parents with intense feelings of love

    - Ian drinks his coffee and talks enthusiastically about his love of singing.

    - people who love democracy

    - I guess Michael and I were trying to find a way to express our brotherly love for one another.

    - So passionate is my love of opera, that I crave any activity that extends my time in the Arts Centre.

    - Years later he has combined his love for zoology with his appreciation of the female form.

    - She dwells on her charming manner, love of clothes, loyalty to her brother and, in later life, to her adoptive city.

    - you're such a love!

    - "Emily, my dear," said the spinster aunt, with a patronising air, "don't talk so loud, love."

    - You did that? I love it!

    - He lost his ambition and forgot everything but his love for this unworthy woman.

    - Brotherly love comes at a price, it seems.

    - He truly did love her, and deep down he knew his family would too, but he was still nervous.

    - All the very very best to you Tom, and lots of love from Charlie.

    - I had a great interest and love of music, and music was always a part of the family, but no one had ever pursued it.

    - Looking forward to seeing you soon, Lots of love, Grannie

    - We also send our best love to you and the children all wish that they were going on the same ship as their Father.

    - Each one is very powerful, but none of them is as strong as your love for your daughter.

    - do you love me?

    - We have always happy together and our love for each other has been strong and growing for sometime now.

    - we share a love of music

    - Try falling in love with someone who is from a different country and speaks a different language.

    - She did not overtly try to attract Edgar, but he was still falling in love with her.

    - My love for her was as strong as ever, as it is now, at this very moment.

    - I'd love a cup of tea

    - It's alright my love you are safe with me.

    - I had to try to put my intense passionate love for him to the side and be his friend.

    - their love for their country
kuyo@DESKTOP-8O0L9BP:~$

どうですか?
便利でしょう?
これはLinuxのShellとかで動作するコマンドなのですが、Windows10にインストールすることも可能です。
ただ、多少手順がめんどくさいので順を追って説明しますね。

Windows10上のコマンドラインと言ってもDOS窓でもなければ、PowerShellでもありません。
WSLです。

WSLはWindows Subsystem for Linuxの略で、マイクロソフトが提供する、Windows10上で動作するLinuxなんですね。
コマンドライン上でLinuxの様々なツールが使えてしまうというスグレモノです。

先ずはWSLのインストールから始めます。
WHLのインストールのために、まずWHLを許可します。
コントロールパネルを開きます。

[プログラム]をクリックします。

[プログラムと機能]をクリックします。

左ペインにある[Windowsの機能の有効化または無効化]をクリックします。

リストの下のほうにある[Windows Subsystem for Linux]のチェックを入れて[OK]をクリックします。

暫く待つと完了します。

PCの再起動を求められるので再起動します。

スタートメニューから[Microsoft Store]を起動します。

検索から[WSL]を探します。

LinuxのDistributionを選びます。
特に好みが無ければUbuntuが良いでしょう。

[入手]をクリック。
インストールされます。

[起動]をクリックするとWSLのコマンドラインが開きます。

暫く待つとuser nameを聞いてきます。

ここで自分の作成したいuser nameを入力します。
私はkuyoにしました。

次にuserのpasswordを聞いてきます。
ローカルの話なので適当に覚えやすいpasswordを設定します。

確認のためにもう一度passwordを入力します。

これでWSLのインストールはおしまいです。
Windows上に仮想的なLinuxが立ち上がったことになります。
しかもUbuntuですからaptで欲しいツールを簡単にインストールすることができます。

ちなみにこのLInux環境のrootディレクトリは以下になります。

C:\Users\%USERNAME%\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\rootfs\

kuyoのhomeは以下ですね。

C:\Users\%USERNAME%\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\rootfs\home\kuyo

ではWSLのコマンドターミナルから必要なツールをインストールします。
先ずはaptのupdate。

kuyo@DESKTOP-8O0L9BP:~$ sudo apt update
[sudo] password for kuyo:

passwordを聞いてくるので先ほど設定したものを入力します。

導入にはいくつかのツールが必要です。
具体的にはgit, gawk, makeが必要なのでインストールします。

kuyo@DESKTOP-8O0L9BP:~$ sudo apt install git
kuyo@DESKTOP-8O0L9BP:~$ sudo apt install gawk

gitとgawkが必要ですが既に最新のものが入っていました。
makeもインストールします。

kuyo@DESKTOP-8O0L9BP:~$ sudo apt install make
kuyo@DESKTOP-8O0L9BP:~$ sudo apt install make-guile

途中”Do you want to continue? [Y/n] Y”と聞いてきますのでyと[enter]キーを押します。
ネットへの接続が必要です。

次にtranslate-shellをダウンロードします。

kuyo@DESKTOP-8O0L9BP:~$ git clone https://github.com/soimort/translate-shell

ディレクトリを移動します。

kuyo@DESKTOP-8O0L9BP:~$ cd translate-shell

makeしてinstallします。

kuyo@DESKTOP-8O0L9BP:~/translate-shell$ make
[OK] Task build completed.
kuyo@DESKTOP-8O0L9BP:~/translate-shell$ sudo make install
[OK] Task build completed.
[OK] translate-shell installed.
kuyo@DESKTOP-8O0L9BP:~/translate-shell$

以上でインストールはおしまいです。
transというコマンドがインストールされました。
使い方は以下で分かります。

kuyo@DESKTOP-8O0L9BP:~$ trans --help
Usage:  trans [OPTIONS] [SOURCES]:[TARGETS] [TEXT]...

Information options:
    -V, -version
        Print version and exit.
    -H, -help
        Print help message and exit.
    -M, -man
        Show man page and exit.
    -T, -reference
        Print reference table of languages and exit.
    -R, -reference-english
        Print reference table of languages (in English names) and exit.
    -L CODES, -list CODES
        Print details of languages and exit.
    -S, -list-engines
        List available translation engines and exit.
    -U, -upgrade
        Check for upgrade of this program.

Translator options:
    -e ENGINE, -engine ENGINE
        Specify the translation engine to use.

Display options:
    -verbose
        Verbose mode. (default)
    -b, -brief
        Brief mode.
    -d, -dictionary
        Dictionary mode.
    -identify
        Language identification.
    -show-original Y/n
        Show original text or not.
    -show-original-phonetics Y/n
        Show phonetic notation of original text or not.
    -show-translation Y/n
        Show translation or not.
    -show-translation-phonetics Y/n
        Show phonetic notation of translation or not.
    -show-prompt-message Y/n
        Show prompt message or not.
    -show-languages Y/n
        Show source and target languages or not.
    -show-original-dictionary y/N
        Show dictionary entry of original text or not.
    -show-dictionary Y/n
        Show dictionary entry of translation or not.
    -show-alternatives Y/n
        Show alternative translations or not.
    -w NUM, -width NUM
        Specify the screen width for padding.
    -indent NUM
        Specify the size of indent (number of spaces).
    -theme FILENAME
        Specify the theme to use.
    -no-theme
        Do not use any other theme than default.
    -no-ansi
        Do not use ANSI escape codes.
    -no-autocorrect
        Do not autocorrect. (if defaulted by the translation engine)
    -no-bidi
        Do not convert bidirectional texts.
    -bidi
        Always convert bidirectional texts.
    -no-warn
        Do not write warning messages to stderr.
    -dump
        Print raw API response instead.

Audio options:
    -p, -play
        Listen to the translation.
    -speak
        Listen to the original text.
    -n VOICE, -narrator VOICE
        Specify the narrator, and listen to the translation.
    -player PROGRAM
        Specify the audio player to use, and listen to the translation.
    -no-play
        Do not listen to the translation.
    -no-translate
        Do not translate anything when using -speak.
    -download-audio
        Download the audio to the current directory.
    -download-audio-as FILENAME
        Download the audio to the specified file.

Terminal paging and browsing options:
    -v, -view
        View the translation in a terminal pager.
    -pager PROGRAM
        Specify the terminal pager to use, and view the translation.
    -no-view, -no-pager
        Do not view the translation in a terminal pager.
    -browser PROGRAM
        Specify the web browser to use.
    -no-browser
        Do not open the web browser.

Networking options:
    -x HOST:PORT, -proxy HOST:PORT
        Use HTTP proxy on given port.
    -u STRING, -user-agent STRING
        Specify the User-Agent to identify as.
    -4, -ipv4, -inet4-only
        Connect only to IPv4 addresses.
    -6, -ipv6, -inet6-only
        Connect only to IPv6 addresses.

Interactive shell options:
    -I, -interactive, -shell
        Start an interactive shell.
    -E, -emacs
        Start the GNU Emacs front-end for an interactive shell.
    -no-rlwrap
        Do not invoke rlwrap when starting an interactive shell.

I/O options:
    -i FILENAME, -input FILENAME
        Specify the input file.
    -o FILENAME, -output FILENAME
        Specify the output file.

Language preference options:
    -l CODE, -hl CODE, -lang CODE
        Specify your home language.
    -s CODES, -sl CODES, -source CODES, -from CODES
        Specify the source language(s), joined by '+'.
    -t CODES, -tl CODES, -target CODES, -to CODES
        Specify the target language(s), joined by '+'.

Text preprocessing options:
    -j, -join-sentence
        Treat all arguments as one single sentence.

Other options:
    -no-init
        Do not load any initialization script.

See the man page trans(1) for more information.
kuyo@DESKTOP-8O0L9BP:~$

ただしこのままでは使いにくいので ~/.bashrc に以下の二行を付け加えます。

alias ej="trans -sl=en -tl=ja"
alias je="trans -sl=ja -tl=en"

テキストエディッタはnanoというものが標準でインストールされているのでそれを使います。
もちろんvimをインストールするのでも良いし、以下のファイルをWindowsのテキストエディッタで直接編集するのでも構いません。

C:\Users\%USERNAME%\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\rootfs\home\kuyo\.bashrc

編集できましたら一度exitコマンドで抜けます。

kuyo@DESKTOP-8O0L9BP:~$ exit   

再度の起動はスタートメニューから行えます。
Ubuntuならば以下のようなアプリが増えています。

いかがでしょうか?
手順は多いのですが、意外と簡単にインストールすることができました。
これで快適な執筆ライフがおくれますね。

WSLは単にtranslate-shellのためだけではなく、様々なツールを使うことができます。
例えば電卓。
bcというコマンドがあります。
これはコマンドラインで計算ができるというスグレモノです。

小説を執筆しているときに距離だとか時間の確認に電卓が欲しい場合がありますが、これもコマンドラインで用が足りてしまうわけです。
変数も使えるし、上下カーソルで履歴も拾えるので普通の電卓よりも高機能だったりします。
終了は quit と入力して[enter]キーを押します。

ご同胞の諸兄姉の執筆ライフが少しでも充実されんことを心より祈りつつ。


挿絵画家になろう(その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]を書きたいと思います。



黒灰色の魔女と時の魔女 第五章第三話(九)更新しています


黒灰色(こっかいしょく)の魔女と時の魔女』、『第五章第三話(九)君、山登れ』更新しています。
砂漠に子供二人、赤ん坊付きでおっぽり出されて、頼れるのは怪しげな砂漠の声だけというシチュエーション。
読んで下さいね。

絵はマリアの幼少期です。
流石にこれ以上は誰も死なないはず。
マリアって将来的には二児の母ですし。

で背景はWord Cloudです。
twitterとかで小説の宣伝画像を作りたいなと思うじゃないですか?
でも絵を作るってメンドクサイですよね?
そんな時にWord Cloudですよ。
私もtwitterを始めたばかりの時はWord Cloud一本で宣伝絵を作っていました。

Word Cloudとは切り出した単語や文章を、重要なものを大きく、そうでもないものを小さく表示して、画面全体を埋める表現手法です。
どのようなキーワードが流行しているかを見える化するツールなわけです。
我々小説家になろうに投稿するものは、小説のキーワードやインパクトのあるフレーズを表示させると良いんじゃないかと思うわけです。

作り方は色々あるのですけれど、お勧めはPython3でword_cloudを使う方法です。

Pythonはスクリプト言語です。
Python3は現状最新版のPythonです。
Python2もまだ現役ですが日本語の取り扱い等でPython3は進化しています。
WINDOWS10 PCへのインストールは「このサイト」を参照してください。
Python3のインストール

環境変数等も設定してDOS窓からPythonが実行できるようにしてください。
DOS窓から

python --version

と打つとマイクロソフトストアが立ち上がってトホホとなる場合は「ここ」を見ると幸せになれるかもしれません。
windowsでpython3を実行するとストアが開く

world_cloudはPython3のモジュールです。
前提となるモジュールがあるのでいくつかDOS窓でインストールを行います。
具体的には以下をDOS窓で実行します。

python get-pip.py 
python -m pip install --upgrade pip
python -m pip install matplotlib
python -m pip install numpy
python -m pip install pillow
python -m pip install wordcloud

pipというのはPythonのモジュールを取得するためのスクリプトです。
pipを使うことにより様々なモジュールをインストールすることができます。
matplotlibと numpy は数値演算系のモジュールで、Pythonプログラマは皆お世話になっているものです。
pillow はPythonの画像系のモジュールでお絵かきする人は知っておいた方が良いモジュールです。
Pythonインストール時、インストールディレクトリとその下のScriptsフォルダにパスを通しておいてください。
例えばC:\Python37にインストールしたのなら以下を環境変数PATHに追加します。

C:\Python37
C:\Python37\Scripts

Pythonのモジュールと言いましたが、word_cloudを使う上ではPythonは単なるプラットフォームで意識する必要はありません。
実際に使うのはword_cloud_cli.exeというコマンドです。
以下のコマンドが実行できるか確かめてください。

c:\work>wordcloud_cli --help
usage: wordcloud_cli [-h] [--text file] [--regexp regexp] [--stopwords file]
                     [--imagefile file] [--fontfile path] [--mask file]
                     [--colormask file] [--contour_width width]
                     [--contour_color color] [--relative_scaling rs]
                     [--margin width] [--width width] [--height height]
                     [--color color] [--background color] [--no_collocations]
                     [--version]

A simple command line interface for wordcloud module.

optional arguments:
  -h, --help            show this help message and exit
  --text file           specify file of words to build the word cloud
                        (default: stdin)
  --regexp regexp       override the regular expression defining what
                        constitutes a word
  --stopwords file      specify file of stopwords (containing one word per
                        line) to remove from the given text after parsing
  --imagefile file      file the completed PNG image should be written to
                        (default: stdout)
  --fontfile path       path to font file you wish to use (default:
                        DroidSansMono)
  --mask file           mask to use for the image form
  --colormask file      color mask to use for image coloring
  --contour_width width
                        if greater than 0, draw mask contour (default: 0)
  --contour_color color
                        use given color as mask contour color - accepts any
                        value from PIL.ImageColor.getcolor
  --relative_scaling rs
                        scaling of words by frequency (0 - 1)
  --margin width        spacing to leave around words
  --width width         define output image width
  --height height       define output image height
  --color color         use given color as coloring for the image - accepts
                        any value from PIL.ImageColor.getcolor
  --background color    use given color as background color for the image -
                        accepts any value from PIL.ImageColor.getcolor
  --no_collocations     do not add collocations (bigrams) to word cloud
                        (default: add unigrams and bigrams)
  --version             show program's version number and exit

c:\work>

作業はc:\workで行うこととします。
必要になるのは以下。
・wordテキストファイル。
表示するキーワードを格納するファイルです。
半角スペースもしくは改行で区切ります。
抜粋ですが以下のような感じです。

黒灰色の魔女と時の魔女
黒灰色の魔女と時の魔女
黒灰色の魔女と時の魔女
黒灰色の魔女と時の魔女
黒灰色の魔女と時の魔女
黒灰色の魔女と時の魔女
黒灰色の魔女と時の魔女
黒灰色の魔女と時の魔女
黒灰色の魔女と時の魔女
黒灰色の魔女と時の魔女
黒灰色の魔女と時の魔女
黒灰色の魔女と時の魔女
黒灰色の魔女と時の魔女
第五章:傍に居てよ
第五章:傍に居てよ
第五章:傍に居てよ
第五章:傍に居てよ
第五章:傍に居てよ
第五章:傍に居てよ
第五章:傍に居てよ
第五章:傍に居てよ
第五章:傍に居てよ
第五章:傍に居てよ
第三話:ずっときみを見守っていたんだ
第三話:ずっときみを見守っていたんだ
第三話:ずっときみを見守っていたんだ
第三話:ずっときみを見守っていたんだ
第三話:ずっときみを見守っていたんだ
第三話:ずっときみを見守っていたんだ
第三話:ずっときみを見守っていたんだ
(九)君、山登れ
(九)君、山登れ
(九)君、山登れ
(九)君、山登れ
(九)君、山登れ
(九)君、山登れ
(九)君、山登れ
マリア
マリア
マリア
マリア
マリア
マリア
マリア
マリア
マリア
マリア
リリィ
リリィ
リリィ
リリィ
リリィ
リリィ
ヨシュア
ヨシュア
ヨシュア
ヨシュア
ヨシュア
ヨシュア
ヨシュア
ヨシュア
ヨシュア
齧りながら
頷く
頷く
呟きながら
麓
緑
稜線
稜線
了解
立ったまま
立ち上がる
立ち上がる

このファイルをC:\work\input.txtとして保存します。
漢字コードはUTF-8を選択します。
数が多いキーワードは大きくなります。
なので数で調整してください。

後、漢字をサポートしているフォントファイルを指定します。
C:\Windows\Fonts\ にある適当なフォントを選択します。
気に入っているフォントがあればそれを指定しても構いません。
私は大好きな「装甲明朝」を使います。
DOS窓で以下のように実行してください。

wordcloud_cli --width 1920 --height 1080 --text input.txt --fontfile C:\Windows\Fonts\SoukouMincho.ttf --no_collocations --imagefile planetext.png

planetext.pngが生成されます。
以下のような感じになります。

マスク画像を指定して文字のある部分と無い部分を作ることもできます。
例えば以下のような画像ファイルを用意します。
image_mask.png

黒の部分に文字が入り、白の部分はマスクされます。
DOS窓で以下のように実行してください。

wordcloud_cli --width 1920 --height 1080 --text input.txt --fontfile C:\Windows\Fonts\SoukouMincho.ttf --no_collocations --mask image_mask.png --imagefile text_w_mask.png

text_w_mask.png が生成されます。

マスクされました。
フォントの色を指定することもできます。
例えば赤を指定したければ以下のようにします。

wordcloud_cli --width 1920 --height 1080 --text input.txt --fontfile C:\Windows\Fonts\SoukouMincho.ttf --no_collocations --mask image_mask.png --color red --imagefile text_w_mask_red.png

カラーマスク画像を使って色調を管理することもできます。
どんな画像でも良いのですがグラデーションやノイズ交じりのものが良いと思います。
例えば次のような画像を用意します。
cmask2.png

DOS窓で以下のように実行してください。

wordcloud_cli --width 1920 --height 1080 --text input.txt --fontfile C:\Windows\Fonts\SoukouMincho.ttf --no_collocations --mask image_mask.png --colormask cmask2.png --imagefile text_w_mask_cmask.png

以下のような画像が生成されます。

後は画像を合成すれば完成です。

いかがでしょうか?
twitter用の画像として手軽で良いと思いませんか?

絵で困ったときはword_cloudの存在を思い出してあげてくださいね。


挿絵画家になろう(その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]を書きたいと思います。


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


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

一般論として3D人体キャラクターの表情を変えることは非常にメンドクサイ仕事です。
特に私が求める絵作りはセルルックなアニメ調のものです。
アニメ的な表現文法でよくあるものは3Dと相性の悪いものも多く、3Dツールでの実現に拘るのは私たち素人にとってあまり良い選択ではないかもしれません。
私たち「小説家になろう」作家が求めているのは3Dアニメーションではなく挿絵です。
ある程度品質の良い3Dキャラクターを入手できたのならば、ポーズを変えてレンダリングし、後は2Dペイント系のツールで表情を書き換えるのが早くて簡単な良い方法だと私などは考えます。

とはいえ、MB-Labは優れた人体3D人体キャラクター生成のソリューションです。
当然キャラクターの表情を変える手段を用意してくれています。
しかも非常に使い勝手の良いものです。
MB-Labでどこまで表情がいじれるか知ることは重要です。
そして何ができるのか? 何ができないのか? を知り、自分の作品に反映させると良いでしょう。

オブジェクトモードであることを確認し、girl1_bodyオブジェクトを選択します。
ツールシェルフの[ManuelBastioneLab]タグ、[FACE EXPRESSIONS]を選択します。

沢山のパラメータが現れます。
このパラメータの一つ一つが表情の選択になります。
半分は発音の音韻に対応するものです。
残りは以下のようなプレフィックスが付いています。

angry: 怒り
annoyed: イライラ
anxious: 心配
attentive: 気配り
bored: 退屈
breathing_in: 息を吸う
breathing_out: 息を吐く
confused: 混乱
crying:泣き
curious: 好奇心
deglutition: 嚥下
disgusted: むかつき
drained: 疲れ
embarrassed: 当惑
evil: 悪い顔
excited: 興奮
flirty: 軽薄
furious: 激怒
grin: にやにや
happy: 幸せ
irritated: 荒れ
lazy: 怠惰
offended: 気分を害した
pain: 痛み
peaceful: 平安
posing: ポーズ
sad: 悲しみ
sarcastic: 皮肉
scared: 怖い
serene: 穏やか
shocked: 衝撃
shy: 内気
sleep: 睡眠
surprise: 驚き
tired: 疲れ
very_sad: 激しい悲しみ
wink: ウィンク

おおお、このパラメータたちを1に振ると、表情が変わるのですね。
試してみましょう

angry01: 怒り

確かに怒っているように見えます。
MB-Labの[FACE EXPRESSIONS]では内部的にBlenderのシェイプキーを用いて表情を変えているようです。
プロパティウインドウのオブジェクトデータ(逆三角形のマーク)の「シェイプキー」が切り替わっているのが確認できます。
変化点は以下。

 Expressions_browSqueezeL_max:1.000
 Expressions_browSqueezeR_max:1.000
 Expressions_browsMidVert_min:1.000
 Expressions_cheekSneerL_max:1.000
 Expressions_cheekSneerR_max:1.000
 Expressions_mouthOpenAggr_min:0.560

眉が吊り上がっているところが良いですね。

annoyed01: イライラ

イライラというほどでもないような……。
口が丁度「え」の発音くらいに開いています。

 Expressions_browOutVertR_max:0.660
 Expressions_browSqueezeL_max:0.960
 Expressions_browsMidVert_min:0.360
 Expressions_eyesVert_max:0.600
 Expressions_jawHoriz_max:0.120
 Expressions_mouthOpenO_max:0.360

anxious01: 心配

かなり複雑な表情です。
右唇を噛んでいる演出ですね。

 Expressions_browOutVertL_min:0.300
 Expressions_browOutVertR_min:0.240
 Expressions_browSqueezeL_max:0.760
 Expressions_browSqueezeR_max:0.420
 Expressions_browsMidVert_max:0.300
 Expressions_eyeClosedL_max:0.300
 Expressions_eyeClosedR_max:0.300
 Expressions_eyesHoriz_min:0.480
 Expressions_eyesVert_min:0.540
 Expressions_mouthBite_min:1.000

bored01: 退屈

退屈というよりはブーイングの表情でしょうか?
文字通りの膨れっ面。

 Expressions_browOutVertL_max:0.780
 Expressions_browOutVertR_max:0.720
 Expressions_browsMidVert_max:0.840
 Expressions_eyeClosedL_min:0.720
 Expressions_eyeClosedR_min:0.540
 Expressions_mouthInflated_max:1.000
 Expressions_mouthOpenO_min:0.480

confused02: 混乱

混乱? 迷いという感じですね。

 Expressions_browSqueezeL_max:1.00
 Expressions_browSqueezeR_max:0.960
 Expressions_browsMidVert_max:0.960
 Expressions_cheekSneerL_max:0.360
 Expressions_eyeClosedPressureL_max:0.060
 Expressions_eyeClosedR_max:0.060
 Expressions_eyeSquintL_max:0.180
 Expressions_eyeSquintR_max:0.120
 Expressions_eyesHoriz_max:0.900
 Expressions_mouthClosed_min:0.780
 Expressions_mouthSmileL_max:0.120

crying01:泣き

目を閉じている演出です。
眉と口を合わせて初めて泣き顔に見えます。

 Expressions_browOutVertL_min:0.360
 Expressions_browOutVertR_min:1.000
 Expressions_browSqueezeL_max:1.000
 Expressions_browSqueezeR_max:1.000
 Expressions_browsMidVert_max:1.000
 Expressions_eyeClosedL_max:0.200
 Expressions_eyeClosedPressureL_max:0.420
 Expressions_eyeClosedPressureR_max:0.420
 Expressions_eyeClosedR_max:0.180
 Expressions_eyeSquintL_max:0.120
 Expressions_eyeSquintR_max:0.120
 Expressions_eyesHoriz_min:0.420
 Expressions_eyesVert_min:0.420
 Expressions_mouthBite_min:0.360
 Expressions_mouthOpen_min:0.180

以下は巻きで紹介しますね。

crying02:泣き

disgusted: むかつき

drained01:疲れ

embarrassed01:当惑

evil01:悪い顔

evil02:悪い顔

excited01:興奮

eyes_rot_down:目を下に

eyes_rot_left:目を左に

eyes_rot_right:目を右に

eyes_rot_up:目を上に

flirty01:軽薄

furious01:激怒

furious03:激怒

grin01:にやにや

happy01:幸せ

irritated01:荒廃

kiss01:キス

lazy01:怠惰

offended01:気分を害した

pain01:痛み

peaceful01:平安

posing01:ポーズ

sad01:悲しみ

sad02:悲しみ

sarcastic01:皮肉

scared01:怖い

serene01:穏やか

shoked01:衝撃

shy01:内気

sleep01:眠り

surprise01:驚き

surprise02:驚き

surprise03:驚き

tired01:疲れ

very_sad01:激しい悲しみ

wink01:ウインク

如何でしょうか?
お気に入りの表情に巡り合えたでしょうか?
私の個人的な好みでは口を閉じている表情は良いものが多いです。
ただ、口を大きく開けている表情は多分このままでは使うことは無いでしょう。
目を閉じている表情でも、笑っている場合はもっと上弦の月のようになるように頬を持ち上げるのが漫画的表情表現なのですが、そのような表情はありません。
笑っている口は下向きのかまぼこのような半円を期待するのですが、それもないのです。
MB-Labの表情はphotorealisticな絵作り用で漫画的表現向けではないのでしょう。

ということで、「小説家になろう」として挿絵を考える場合は、ある程度表情を作ってレンダリングし、後は好みに合わせて2D系のペイントツールで画像加工すると良いのでは? という提案になります。

ちなみに MB-Labの[FACE EXPRESSIONS]を使わず、シェイプキーを直接変更しても表情は変わります。
注意しなければならないことは、 [FACE EXPRESSIONS] 使って シェイプキー で微調整、といった使い方はうまくいかないことですね。
[FACE EXPRESSIONS] でどのシェイプキーが変わるかを把握して、シェイプキーで改めて表情を作りこむといった方法が良いのではないでしょうか?

本記事、予想外に長くなってしまいました。
本当は別の事を書こうと思っていたのですが辿り着けそうにありません。
いったん切ります。
とはいえ、表情も作れるようになり、「挿絵画家になろう」という目的には近づけたのではないでしょうか?

時間があれば[その7]を書きたいと思います。


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


「挿絵画家になろう(その5)」です。
Blenderのアドオン、MB-Labの啓蒙です。
前回までで、MB-Labを使って少女キャラクターを生成し、VRoidStudioの髪をインポートして装着させ、そこそこの服を着せるところまで実現しました。
今回は前回に引き続きマテリアル関連です。

人形は顔が命です。
3Dキャラクターとて例外ではありません。
3Dキャラクターのメッシュを弄って顔を弄るのは容易ではありませんが、テクスチャの加工ならばなんとかなるかも知れません。

前回は服のマテリアルに [girl1_MBLab_anime_skin] を流用しました。
しかしそもそもこのマテリアルは何なのでしょうか?
skinというくらいだからキャラクターの皮膚のマテリアルなんだろうな、と想像できます。
MB-Labのアニメ系のキャラクターを生成し、アニメ調の女性髪型[hair_anime_female]を適用した時点で、以下のマテリアルが存在することになります。

・girl1_MBLab_anime_eyes
・girl1_MBLab_anime_skin
・girl1_MBLab_generic
・girl1_MBLab_toon_black
・MBLab_anime_hair.001


それぞれの割り当てとともに見てゆきましょう。

・girl1_MBLab_anime_eyes: MB-Labキャラクターの目のマテリアル

・girl1_MBLab_anime_skin:MB-Labキャラクターの皮膚のマテリアル


・girl1_MBLab_generic: MB-Labキャラクターのパンツ、ブラジャーのマテリアル


・girl1_MBLab_toon_black: MB-Labキャラクターの眉毛、睫毛のマテリアル

・MBLab_anime_hair.001:髪の毛のマテリアル

衝撃の事実が判明してしまいました。
パンツとブラジャーは穿いていないのです。
単なるボディペイントだったのですね……。
girl1_MBLab_generic の色を変えると、パンツとブラジャーの色が変わりますし、割り当てを変えると取っ払うこともできます。

それはともかく、顔に関係するマテリアルは以下の 三つであることが分かりました。
・girl1_MBLab_anime_eyes
・girl1_MBLab_anime_skin
・girl1_MBLab_toon_black

girl1_MBLab_anime_skin はセルルックな絵作りを決める重要なマテリアルです。
主要なノードを見ていきましょう。
上にあるViewのセレクタ([Default]となっている横の[△]ボタンか[▽]ボタン)を右クリックして現れる選択肢から[Composing]を選択すると3Dビューとノードエディッタ、UV画像エディッタを表示できて便利です。

[skin_oil_val]:テカリの明るさを決めます。
[skin_oil_size]:テカリのサイズを決めます。
テカリは夏の水着の肌でよくある表現です。
カメラに直交する面の一部が明るくなります。
[skin_oil_val] を大きくするとテカリはより明るくなります。
[skin_oil_size] は0にすると最小になり1にすると全体がテカリになります。
0~0.1程度の範囲内で使うべきでしょう。

[ノーマル]:影のできる方向を決めます。
セルルックの絵作りの場合、ライトにより肌の色を決めているのではなく、放射diffuseにより自発光させてマット感を出しています。
その色分けは法線(ノーマル)とオブジェクト表面の角度により行っています。
この[ノーマル]を回転させると「 普通」・「暗いところ」の位置を変えることができます。

[skin_secondary_val]:影の部分の明るさを決めます。
0にすると影は無くなり、1にすると影は真っ黒になります。

[skin_outline_size]:輪郭線の太さを決めます。
1にすると輪郭は消えます。
小さくすると輪郭は太くなります。
0.9~1.0の間で使うべきでしょう。
[skin_outline_val]:輪郭線の明るさを決めます。
1にすると黒になります。
小さくすると色味が消えてゆきます。
柔らかい絵作りをしたければ輪郭を太くして色味を抑えると良いでしょう。

[skin_saturation]:肌の色味を決めます。
1にするとオレンジに偏向、0にすると青に偏向してゆきます。
[skin_value]:肌の明るさを決めます。
1にすると明るく、0にすると黒くなります。
[skin_hue]:肌の色相を決めます。
緑色の皮膚や青い皮膚にすることができます。
私はデフォルトから変えたことがありません。

[Anime_mblab_skin_diffuse]: girl1_MBLab_anime_skin で割り当てるテクスチャ画像です。

[Anime_mblab_skin_diffuse] にはFinalize の際に保存したファイル名の画像が設定されています。
※ここではgirl11_body_derm.png
画像は左下プレーンのUV画像エディッタ―で表示することができます。
この肌色の画像がgirl1_bodyの肌テクスチャです。
このままでは良く分からないのでUVマッピングを生成します。
右下の3Dビュープレーンで編集モードに切り替えます。
モデルの上で[a]キーを押すと全選択になります。

左下のUV画像エディッタ―の[UV]メニューから[UV配置をエクスポート]を選択し、 girl_body_derm_uv_map.png としてセーブします。

GIMP2で girl_body_derm.png と girl_body_derm_uv_map.png とをレイヤとして開きます。

後はgirl1_body_derm.pngを好きなように編集すれば好みの顔に変えることができるわけです。
頬紅、アイシャドウ、口紅などですね。

次の図はgirl1_body_derm_mod.pngとして化粧を施し、 [Anime_mblab_skin_diffuse] に再読み込みしたものです。

頬と唇が赤くなりました。
これだけでかなり印象が変わります。

しかし目を変更しているのですが反映されません。
目のマテリアルは[ girl1_MBLab_anime_eyes ]なのでそちらを変更する必要があります。

編集モードにしてgirl1_MBLab_anime_eyesを選択します。

[girl1_MBLab_anime_eyes]マテリアルの[Anime_mblab_eye_diffuse]ノードにはgirl11_body_derm.pngが割り当てられています。

これをgirl1_body_derm_mod.pngに変更します。

目のテクスチャを差し替えることができました。
[girl1_MBLab_anime_eyes]マテリアル にも色々なノードがありますが、特に重要なのは以下の二つです。

[eyes_fue]:目の色相を決定します。
[eyes_saturation]:目の色の彩度を決定します。

目の色は挿絵を欲する同胞の諸兄姉もコダワリポイントであると思います。
色々試して自分の好みに合わせてください。

残るは[girl1_MBLab_toon_black]マテリアルです。
眉毛と睫毛に割り当てられているものです。
defaultでは黒く、目がハッキリとしています。

編集モードにしてgirl1_MBLab_anime_eyesを選択します。

[girl1_MBLab_toon_black]マテリアル の[放射]ノードのカラーを変更することにより色を変えることができます。
髪の毛と似た色味にするとよいでしょう。

girl1_MBLab_toon_black のスロットに MBLab_anime_hair.001 を割り当ててしまうと、髪の毛と眉毛、睫毛を同じ色にすることもできます。

ポーズを付けてレンダリングしてみました。

如何でしょうか? かなり顔立ちの印象が変わったかと思います。

MB-Labの凄いところは、ほぼほぼ何でも弄れるのですが、優れたマテリアル構成により2Dテクスチャの変更とパラメータ変更だけでかなり思い通りの絵作りができることです。
ここまで3Dメッシュは一切弄っていないことに注目してください。
2Dテクスチャを多少弄れれば、それでかなり思い通りの絵作りをすることができるのです。
これは凄いことですよね?

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


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


「挿絵画家になろう(その4)」です。
Blenderのアドオン、MB-Labの啓蒙です。
前回までで、MB-Labを使って少女キャラクターを生成し、簡素な服を着せ、VRoidStudioの髪をインポートして装着させるところまで実現しました。
今回はマテリアル関連です。

MB-Labはキャラクター造形に関して、相当弄れます。
MB-Labの変数パラメータの組み合わせだけでもかなりのバリエーションを生み出すことができるし、イニシャライズした後はそれこそ単なるBlenderのオブジェクトなのでメッシュを弄り放題です。
実際のところMB-Labを入口にして3Dドールアニメーションの世界に入るのは全然ありだと思います。
しかし、この世界って深くて険しいんですよね。
我々『小説家になろう』作家が自作小説の挿絵を簡単に生成したいという目的で安易に足を踏み込むと小説を書く時間は取れなくなることでしょう。

そこでできるだけメッシュを弄らず、マテリアルの変更で変化を出していくことは良い方法だと思うのです。
幸いなことにMB-Labには秀逸なマテリアルが用意されていて、デフォルトでトゥーンレンダリングが実現できています。
トゥーンレンダリング とは「普通」・「明るいところ」・「暗いところ」などの三諧調程度の色塗りと輪郭線を特徴とする絵作りの方法です。
3Dで直接アニメ調の絵作りができてしまっているのです。

今回は服のマテリアルに関して説明を試みましょう。
※過度な期待は禁物です。

先ずは服です。
前回は袖なしTシャツを着せました。
ただ、やはり薄着すぎて可哀想です。
袖なしTシャツを改造してワンピース用の素材を作成しました。
ここ』においておきます。
Onepiece_Plane.zip

このZIPファイルは以下のファイルを含みます。
・Onepiece_plane.obj
・Onepiece_plane.mtl
・Onepiece_t.png
・Onepiece_uv_map.png

Onepiece_plane.obj をインポートしてください。
※袖なしTシャツはRemove fittingした後、[delete]キーで削除しておきます。

インポートすると例の如く、girl1_bodyのキャラクターを挟み込むように二枚のplaneであるOnepiece_Planeが現れます。
中心を気にしながら大きさと位置を合わせます。

だいたいこの図のように合わせれば良いと思います。

Onepiece_Planeを右クリックして選択されていることを確認したのち、編集モードに切り替えます。

編集モードのまま、上にあるViewのセレクタ([Default]となっている横の[△]ボタンか[▽]ボタン)を右クリックして現れる選択肢から[Composing]を選択します。

上プレーンのノードエディッタ―の表示は上の図のようになっていると思います。
※もしなっていなければ、ノードに『マテリアル』、[Onepiece_Plane]を選択してください。

ノード:[Onepiece_Plane]のノードは全て不要なので削除します。
ノードの上で[a]キーを押すと全て選択できますので[delete]キーを押し、削除します。

ノードエディッタのマテリアルの選択から[girl1_MBLab_anime_skin]を選択します。
前回同様、ノード構成をコピーするためです。

ノードエディターで[a]キーを押下して全てのノードを選択後、[ctrl + c]でノードをコピーします。
そしてコピーしたノードを[Onepiece_Plane]のマテリアルノードに[ctrl + v]で貼り付けます。

ノードエディターの右下に[Anime_mblab_skin_diffuse]がありますので画像ファイルとして[Onepiece_t.png]を開きます。

レンダリングでは以下のようになります。

取り敢えずワンピースを完成させましょう。
上にあるViewのセレクタを[Default]に戻します。
そしてクロスシミュレーションに必要な頂点グループを追加します。

そしてクロスシミュレーションを実施します。
パラメータは次の図参照。

仕上がりは以下のようになります。

縫合しきれていないところが黒い筋として残りますが、気になるならばメッシュを弄って手動で縫います。
ただ、挿絵にするならばレンダリング後に2D系のペイントツールで処理したほうが圧倒的に早いです。

ここで Onepiece_t.png を思い出してください。
Onepiece_t.png は現時点ではピンク一色の1024X1024ピクセルの画像です。
なのでワンピースはピンク色になります。
Onepiece_t.png を編集することにより自由にワンピースの柄を変えることができます。
私はGIMP2を使っています。
GIMP2はフリーソフトでありながらフォトレタッチ系のソフトではphotoshopと双璧を成す凄いアプリケーションソフトです。
使われていない場合は是非インストールして試されることをお勧めします。

GIMP2でOnepiece_t.pngとOnepiece_uv_map.pngをレイヤーとして開いてください。
レイアウトはともかく画像は以下のように表示されると思います。

Onepiece_uv_map.pngで示されているのはワンピースUVマッピングです。
右側にワンピース前面のメッシュが、左側に後面のメッシュが対応します。
それぞれの位置の画像を変更すればワンピースのテクスチャも変わるわけです。
すこし弄ってみましょう。
百花繚乱』様から素材をお借りましす。

Onepiece_uv_map.png のレイヤは不可視にして Onepiece_t_mod.png としてエクスポートします。
Blenderの方では先ほどのノードエディターの右下、[Anime_mblab_skin_diffuse]で[Onepiece_t_mod.png]を開きます。

ワンピースが花柄Tシャツとピンクのスカートに変わりました。
このように一つワンピースを作っておくとテクスチャを差し替えることにより様々なバリエーションを生み出すことができます。
前回出てきた『VRoidStudio』などはコミュニティで、服のテクスチャを工夫することによりワンピースからドレス、メイド服、戦闘服などを作成していて楽しそうです。
同様のことがBlenderベースのMB-Labキャラクターに適用可能です。
ただ、2Dテクスチャの作成も、これはこれで深く険しい道なので、折り合いを付けて程々に歩まれることをお勧めします。

ポーズを付けてレンダリングしてみました。

MB-Labは トゥーンレンダリング 用の優れたマテリアルノードを用意してくれています。
ノード構成そのものはそこまで複雑ではないため、マテリアルノードの学習用の素材として非常に適切なものです。
私などはほぼdefaultでNormalの変更だけで利用させていただいています。
MB-Labの優れたところは、利用しやすいように各機能が用意されていることです。
blenderの知識は必要ですが、これだけ至れり尽くせりで応用の効くソリューション、凄いです。
これは世に広めていかなくちゃならないと、そう思うのです。

今回はこれで終わりです。
服のマテリアルの説明と言っておきながら、テクスチャ設定で終わってしまいました。
時間があれば[その5]を書きたいと思います。