background

スポンサーサイト

--年--月--日(--)

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


多段モーフの多段制御

2017年03月30日(Thu)

1. やたらと長い前置き

Poserにはカタカナ用語がたくさんあって、最初にまとめて覚えようとして挫折したり、わからないなりに把握してたり、という人も結構いるんじゃないかと思う。

たとえばジオメトリ。「OBJのことでしょ?」と言われれば、まあその通りだ。じゃあ「オブジェクト」と「ジオメトリ」は同じものだろうか? そう聞かれると、内心焦ってしまったりするんじゃないだろうか。

ジオメトリ (Geometry) は「図形」や「幾何学」という意味だ。つまり形状、モノのカタチそのものを指す。一方、オブジェクト (Object) はソフトによって微妙に使われ方が違うけど、基本的により抽象的なモノ、存在そのものを表す。例えばPoserの背景や大気は確実にシーン内に存在し、特性や独自のマテリアルも持つオブジェクトだけど、ジオメトリを持たない。

170330-01

逆にVictoria 4.2に仕込まれたマグネット群にはカタチがないけど、あれは「存在しない」というジオメトリを読み込んでいる。ライトやカメラは表示用のジオメトリを持っているけど、あれは言わばガイドのようなもので、そこから光が発せられていたりするわけじゃない。

ヤヤコシイネ。

Poserのジオメトリは基本的にWavefront OBJ形式で記述されている。まず頂点があり、その頂点を直線で結ぶことでポリゴンが定義される。ポリゴンとは多角形の意味で、だいたいは三角か四角のどちらかだ。まれに線が閉じられず、面を持たない線ポリゴンというものも存在する。ダイナミックヘアーのガイドヘアーは線ポリゴンだ。

そして面ポリゴンがたくさんたくさん繋がって、立体のカタチを作り上げている。一見なめらかな表面でも、表示スタイルを変更してやれば、そのオブジェクトが複雑なジオメトリを持っていることがわかるだろう。

170330-02

さて、ここからちょっと若返る時間。

三次元空間の中にある、一つの頂点をPと呼ぼう。Pointの頭文字をとってPだ。この頂点Pがどこにあるかを定義するためには、X軸、Y軸、Z軸、それぞれの座標を求めればいい。頂点PのX軸座標はpxで、Y軸座標はpy、Z軸座標はpzだったとする。そのとき、「頂点Pは(px, py, pz)にある」と定義することができる。ジオメトリファイルの中には、そんな感じの座標が大量に記録されている。

でもってこの頂点Pを、別の位置に動かした。具体的にA地点まで動かした。A地点の座標はax, ay, azだ。さて、頂点Pはどれだけ動いただろう。

170330-03

「どれだけ変化したのか」を知りたい時、それは「変化した後の状態」から「変化する前の状態」を取り除いてやることで求めることができる。例えば財布の中の1万円が9千円になったとしたら、その変化の量は9000-10000=-1000。マイナス千円変化した、ということになる。変化の量がマイナスだから、減ったわけだ。

つまり頂点Pが元の位置からA地点に移動したとき、位置は(ax-px, ay-py, az-pz)だけ変化したということになる。変化した量というのは引算なのだ。なので数学の世界ではこれを差分 (difference)の頭文字d、さらにはギリシャ文字にしてΔ(デルタ)と呼んだり書いたりする。モーフターゲットの中に含まれるデルタとは、名前からして「どれだけ変化したか」を意味しているのだ。

170330-04

ところで、このデルタ内に記録されている数値はダイヤルを1にしたときの変化量だ。ダイヤルの値が2なら2倍移動するし、-0.5なら逆方向に半分だけ移動する。

170330-05

ということは、モーフターゲットは直線にしか移動できない、ということだ。ファギュアのパートやマグネットのように、回転させることはできないのである。


2. モーフの足し算

モーフターゲットは頂点一つ一つにつき、その頂点がXYZの各軸でどれだけ移動するかという情報を持っている。言い換えれば、三次元空間のどの方向にどれだけ移動するかという情報を持っている。向きと大きさを持つ量、それすなわちベクトルである。わかりやすく言えば、矢印だ。

ところで、モーフターゲットは複数を組み合わせることができる。BlinkとSmileのダイヤルを両方1にしたとき、あるいはMuscleとSkinnyを両方1にしたとき。どちらか片方だけが有効になるというとはなく、両方の値が反映されている。これはどういうことだろう。

頂点PがA地点へ移動するモーフターゲットMorphAと、それとは別にB地点へ移動するモーフターゲットMorphBがあったとする。

170330-06

ベクトル同士の足し算は、一方の矢印をもう一方の先に継ぎ足すことで表される。平行四辺形を描いて、対角線を引く形だ。

170330-07

ベクトルの足し算には交換法則が成立するので、どちらにどちらを継ぎ足しても結果は変わらない。これがベクトル同士の掛け算になると、別次元に飛び出す方角が変わったりするんだけど。

そんなわけで、MorphAとMorphBを両方とも1にしたとき、頂点Pは新たな位置A+B地点に移動することになる。

170330-08

3. モーフ間の移動

では次に、こんな感じの二つのモーフターゲットがあるとする。

170330-09

うん、ついさっき見たような気がするけど、まあ置いといて。

今度は、頂点PをA地点まで移動させた後で、さらにA地点からB地点まで移動させたい。どのような操作をすれば、頂点Pは希望通りに動いてくれるだろうか。

170330-10

MorphAとMorphBを足す? すると、こんな風になってしまう。

170330-11

A地点からB地点に移動するということは、言い換えれば「A地点にある」という状態から「B地点にある」という状態に変化したわけだ。変化した量を求めるにはどうすればよかっただろうか。新しい状態から元の状態を取り除くのだ。つまりMorphBからMorphAを引き算してやればいい。

ベクトルの引き算は、マイナスのベクトルを足し合わせることで表現される。マイナスのベクトルとは反対方向を向いた同じ大きさのベクトルだ。つまり、こんな感じ。

170330-12

ここで新たなベクトル、MorphAtoBが誕生する。MorphAtoBはMorphBからMorphAを引いたモーフターゲットだ。MorphAが1の時にMorphAtoBを加えると、頂点PはA地点からB地点へと移動する。

MorphA + ( MorphB - MorphA ) = MorphB

「わざわざ新しいモーフを作らなくても、MorphAを0にして同時にMorphBを1にしたらいいんじゃないの?」という疑問はもっともだ。実際のところ結果自体は変わらない。しかし、一度値を1にしてまた0に戻すという操作は、一度1にしてあとはずっとそのままという操作よりは複雑だ。数が増えるほど管理が大変になるだろう。

じゃあ次に、B地点からC地点へ移動させたい。

170330-13

どんなモーフターゲットを加えてやればいいか。そう、MorphCからMorphBを引いた新しいモーフターゲット、MorphBtoCを加えるのである。

170330-14

MorphA + ( MorphB - MorphA ) + ( MorphC - MorphB ) = MorphC

こんな風に差分を作ってしまえば、直線移動しかできないモーフターゲットでも、途中で折れ曲がるような動きを表現できる。数を増やせばなめらかに動いているようにも見せかけることができるだろう。先人はこれをSegmented Morph Targetと呼んだ。適当な邦訳は探してみたけど今となっては見つからなかった。「分割化モーフ」だとまるで左右に分割するSplit Morphみたいだし、「細分化モーフ」だとなんだかサブディビジョン絡みのようだ。「多節モーフ」や「連続モーフ」も考えたけど、それならいっそ「多段モーフ」でいいんじゃないだろうか。

というわけで、自分は複数の中間モーフを用いて多角形的な動きを再現する手法Segmented Morph Target多段モーフと呼ぶことにする。

4. ERCによる多段制御

しかし、これだけではまだ制御というには不十分だ。なぜなら、現時点ではモーフターゲットのダイヤルを手作業で操作しているからだ。

今、MorphAのダイヤルを1にして、次にMorphAtoBを1にした。次はMorphBtoCのダイヤルを1にしなければならない。この一連の動きをまとめて、一つのパラメータダイヤルにしてしまいたい。

するとERCこと、公式名Dependent Parameterを仕込むことになる。

適当なパートに適当なパラメータを作り、それをマスターパラメータとする。そして各モーフターゲットをスレーブパラメータにする。では、それぞれのモーフターゲットがどのような値を取ればよいか、グラフにして確認してみよう。マスターパラメータの値をここではTとして横軸にとり、各モーフターゲットの値Vを縦軸にとる。

170330-15

最初のMorphAの動きは簡単だ。マスターが0の時MorphAは0であり、あるタイミングTaで1になる。1よりも大きい値になることはない。0未満になることもない。

170330-16

従来の差分増加型 (ValueOpDeltaAdd) を使うなら、傾きは1/Taだ。そして最大値と最小値を設定してやればいい。

しかし、それ以降のモーフターゲット、たとえばMorphAtoBはどうだろう。モーフAが1になるタイミングTaから動き始め、あるタイミングTbで1となる。

170330-17

一定の範囲でのみ稼働するモーフターゲット、というのは昔から需要があった。たとえば腕を120度回転させてから170度回転するまでの間稼働するモーフターゲットとか。

そんなわけでこの動きを実現するために、ざっくり3種類の手法があった。

一つ目は、確かカスケードJCMとか呼ばれていた手法。上限と下限を制御する二つの空パラメータを作り、それを合成する手法だ。

170330-18

たぶんDAZフィギュアでいって第三世代から第四世代の最初ぐらいまでスタンダードだった手法だ。自分も何度か服を配る時に組んでいた記憶がある。とりあえず、設定値を考えるのがとことんめんどくさいことがデメリットかな。制御対象一つにつき二つの空パラメータが必要なことも煩雑さの原因になっている。

次にValueParam Oneを使うMulti-stage JCM(多段JCM)という手法。まず自分自身のどこかに(フィギュアならBODYとかに)常に1を出力し続ける空の隠しパラメータを仕込んでおく。そして必要な分だけ数を掛け、定数項として加算する。さらに上限と下限を設けることでディレイを実現する。

170330-19

詳細な説明は枡久田マスクさんが紹介なさっている。Antoniaというフィギュアの作者、ODFさんが発明されたらしい。カスケードJCMに比べて数値の設定が簡潔で、普通のERCを用いているのでDAZ Studioでも互換性が保たれる(はず)。

三つ目は、Poser 8から可能になったキー制御型連動パラメータを使用する方法だ。作成方法自体は先日記事にしたのでそちらを確認してほしい。

170330-20

キー連動型のメリットとしては、上限や下限の値を特に設けなくても一定範囲以上には変化しないことだ。またPoser上で実際に操作しながら値を設定できるので、非常に直感的でもある。

ただし、キー間はスプライン補完されるため、他にキーを増やしてしまうと予想外の動きをしてしまう恐れがある。また互換性という点では後方互換がPoser 8まで、DAZ Studioにはおそらく非対応だろうというデメリットがある。

一つ目の方法は本当にややこしいし、現在取り入れるとしたら二つ目か三つ目の方法だろう。これらの複数のパラメータを一つのパラメータで段階的に変化させる手法を、Multi-Stage JCMから発展させて多段制御 (Multi-Stage Control)と呼ぶことにする。いやだって、JCMに限った手法じゃないしさ。

5. 実際の組み込み

前回の記事のアニメーションGIFは、まず4つの地点のモーフターゲットを作成し、次に辿りたい経路の差分を作成した。

170330-21

説明のために残してあるけど、MorphB、MorphC、MorphDは一度差分を作ってしまえば使用することはないので、削除してしまって構わない。

そして別の小道具、球体のX軸移動をマスターとして、それぞれにキーを記録した。細かい数字を入力するのが面倒だったので、0.1[PU]ずつ移動したらモーフが切り替わるようになっている。0.5[PU]まで移動したらD地点から元の位置に戻る。シーンファイル内の記述はこんな感じだ。

170330-22

はたして。

ERCまわりのギミックはものすごく奥深いんだけど、まだまだ把握しきれてないんだよねー。

170330-23

本当に知らなかったんだってば(ググった)。



Comments

詳細で面白い解説、有難うございます(^^

う~む、
と思いっきり唸った後・・・

自分が作成しているモーフはベクトルの足算モーフだったのですね。
モミモミやモミリータで、目の開閉とスマイルのモーフを合わせて使えるのはその為でした。
疑問を抱きつつ、ラッキーと思いつつ使っていたのですが、その仕組みが良くわかりました。

それを引算にすると、6面体を移動させたモーフに成る言うのも、ベクトル図形で理解できました。
それをERCに組込んで多段制御する方法の理解は、Poserで組み込むERC、を読みながら実践する必要が有りそうですが、仕組みが分かったので自分でもできそうと希望が持てました。

しかし、ベクトルの足算引算の概念、面白かったです。
もしかして小学校あたりで習ったのではと思うのですが、自分としては新鮮な思いで読ませて頂きました。

Name
sannzi #u2lyCPR2
Site
URL
Post Date
2017-03-31
Post Hour
00:32:19

Edit

お待たせいたしました~

>sannziさん
参考になりましたでしょうか。
一口にモーフといってもフルボディモーフやらJCMやら色々ありますが、基本はsannziさんのおっしゃるように、表情など一つのパート上でダイヤル操作するモーフターゲットですね。ダイヤルを組み合わせてSpawn Morph Targetするのは、足し算の結果を残すことだった……とも考えられます。

今回は抽象的な説明がほとんどなので、実作業については言葉の足りないところもあると思います。わからないところがあったら、いつでもお尋ねくださいね。

ベクトルを習うのは高校の数2だそうなので、選択したコースなどによっては全くやらないこともあるらしいです。が、矢印の合成自体はもしかしたら中学校の理科で(力の合成として)習っているかもしれません。
どちらにしても、もはや記憶の遠く……(^^;

Name
Kyotaro #NWbyPjWY
Site
URL
Post Date
2017-03-31
Post Hour
01:58:17

Edit

ベクトル

私がベクトルを知っていたのは、小中学生向け科学雑誌に解説が載っていたからです。
ただしこの様に二次元ではなく、直線上、一次元のベクトルの足算引算でした。
なので、それが二次元図でベクトルを表すとこう成るのだなと、とても新鮮な思いがしました。

きっとベクトル同士の掛け算となると、次元の違う難しさに成るのでしょうね。
なんだか怖いけど、暇をみて調べてみたい気がないでもないです・・・

Name
sannzi #u2lyCPR2
Site
URL
Post Date
2017-03-31
Post Hour
18:39:48

Edit

おそるべし子供向け科学雑誌!

>sannziさん
なるほど~。ベクトルのファーストコンタクトは科学雑誌だったのですね。
それにしてもsannziさんの守備範囲の広さにはいつも驚かされます。

ベクトルの掛け算は次元が増えたり減ったりなかなか面白いですが、
ベクトル関数あたりになると自分ではもう単位を取るのが精一杯でした(--;

Name
Kyotaro #NWbyPjWY
Site
URL
Post Date
2017-04-01
Post Hour
00:04:47

Edit

Post Comment

管理者にだけ表示を許可する


Trackback

※このブログにトラックバックを送信する場合、お手数ですが本文中にブログ該当記事へのリンクを含めてください。

トラックバックURL:http://rutenshikai.blog63.fc2.com/tb.php/560-a31f9c77



Menu

Profile

Kyotaro

確定名:Kyotaro
ネタを探しているらしい。

Categories

Calendar

04 | 2017/05 | 06
- 1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31 - - -

Comments

Archives

Track back

RSS feed

Links

Search

※2011年4月6日のサーバ障害の為、エントリのアドレスが以前のものからズレています。当Blogのエントリにリンクを張っておられた方は、お手数ですがアドレスのご確認をお願い致します。

※Internet Explorer非推奨。


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。