株式会社デジタル・フロンティア-Digital Frontier

Header

Main

  • TOP
  • DF TALK
  • ≪セットアップ室≫ポリゴンで作られた髪の毛のセットアップ 第一回 ~仕様決め編~

≪セットアップ室≫ポリゴンで作られた髪の毛のセットアップ 第一回 ~仕様決め編~

2015/4/9

Tag: ,,,,,,,

はじめまして、セットアップ室の池田です。
髪の毛のセットアップについて、少し書きます。

●はじめに
自分自身が経験した髪の毛のセットアップパターンは大別して2つです。

今回は髪の毛がポリゴンオブジェクトの場合のセットアップ方法について書いていきます。

●まずは手作業で
髪の毛のセットアップの場合、オブジェクト数の多さがネックです。
ポリゴンでフサになっていても100本以上あったりします。hair shaderだと1000本単位が普通です。
何度も同じことを繰り返す必要があります。これはスクリプトの出番ですね。
ただ、一度は手で作らないと安心できません。手探りでスクリプトを書くと逆に時間がかかる場合もあります。
そこで計画を立てます。

=======================================================

カーブ1本(1フサ)だけ手作業でセットアップして仕様を決める

工程ごとにスクリプト化して全部の髪の毛をセットアップ

ツール化する

=======================================================

本稿では計画の中の、手作業で1フサ分のセットアップをして仕様を固めるまで
を書いていこうと思います。
次回があればスクリプト化していく工程に移り、回をかさねて完成に近づけていきたいな、と思います。

●頭部のオブジェクト、骨を用意
まず頭と髪の毛のモデルが無いと作れません。 これ以上ないぐらいシンプルにします。

1、顔オブジェクトと髪の毛オブジェクト(角みたいなの)を作ります。
2、頭の骨を作り”head_JT”と名づけます。
3、顔オブジェクトを骨でバインドします。(髪の毛オブジェクトはしません)

●髪の毛のジョイントを作成
髪の毛のポリゴンの中心を通るジョイントを作ってバインドします。

こんな感じです。
名前は”hairCrv1JT”,”hairCrv2JT”,”hairCrv3JT”…とします。

●ジョイントからIKスプラインを作る
先程の骨をIK Spline Handle ToolでIKスプラインをつくります。

名前は、
IKハンドル名…hairCrv1IK
カーブ名  …hairCrv
とします。

●カーブからmayaHairを作る
先程、出来たカーブを複製してmayaのnHairを作成します。

カーブを選んだ状態で以下をメニューから実行してHairを作ります。
nDynamics > nHair > Assign Hair System > New Hair System

なにか沢山出来てしまいましたね。

ひとまずこんな風にリネームと階層整理をします。

==========================================
新しい親グループ…mayaHair_GP
—-follicleの下にあるカーブ…inputCrv
—-follicle1
—-hairSystem1
—-nucleus1
—-”hairSystem1OutputCurves”の中にあったカーブ…outputCrv ==========================================

考え方として「入力」、「制御」、「出力」の3つに分けて考えると分かりやすいかもしれません。
==========================================
inputCrv… Hair入力カーブ

follicle1 … Hair 1本 を制御する
nucleus … Hair 全体 を制御する
hairSystem1 … Hair 全体 を制御する

outputCrv … Hair出力カーブ
==========================================

●IKスプラインとHairをつなげる
先程名前をつけたHairの出力カーブとIKスプラインカーブをつなげます。

outputCrvShape.worldSpace から hairCrvShape.create へとコネクトします。

ここで一度再生ボタンを押してみましょう。

このようにヘタッと髪の毛が動けば、ここまで成功です。

●コントローラーを作る
コントローラーとして使用するロケーターを用意します。

名前はinputCrv0,inputCrv1,inputCrv2…とし、カーブの頂点数分、用意します。

●重くなる原因
このコントローラーをカーブの頂点にリグを組んで繋げる訳ですが、方法はたくさんあります。
最も量産される箇所です。
ここでどれだけ軽量化できるかが大事になります。

ポイントは2つ
・ノード数の多さ
・各ノードの重さ
です。

今回、最終的に100本の髪をセットアップする予定です。
コントローラーはカーブ1本につき5つと仮定します。(実際は今回4ですがキリが良いので)
そのコントローラーの間には二つをつなぐ為のノードが作られます。仮に2つ、としましょう。

するとコントローラーとカーブ間にはいくつのノードが出来るでしょうか。
単純な計算式をたててみます。
カーブの数×コントローラーの数×つなぐためのノード数=最終的に作られるノード数
最初、つなぐためのノード数が2だと、
100 × 5 × 2 = 1000
これを6つになると、
100 × 5 × 6 = 3000
2000個も増えてしまいました。何の気なしに+3しただけで、最終結果が2000もの差が出てしまいました。
こういう倍々で増える箇所は慎重に決めないといけません。
さらに、ノードによって処理の重さは様々です。
通常のセットアップでは良く使う”pointConstraint”も、ここでは使用しません。
”pointConstraint”はノードはひとつにまとまってますが、実は内部でそこそこ複雑な処理をしています。
実質的に何個もノードを増やしたのと同じです。これが何千個もあるとかなり負担になります。

●コントローラーの位置を決める
カーブの頂点からコントローラーの位置を取得します。
”inputCrv”のカーブのシェイプ”inputCrvShape”のcontrolPointsと各コントローラーのtranslateをコネクトします。

これでコントローラーの位置が取得できました。

コネクションしたばかりですが、目的は達成したのでコネクションを切断します。

●コントローラーとHairをつなげる
次はコントローラーの機能を持たせます。
Hairの入力カーブはinputCrvでした。これを制御します。
各コントローラーのtranslateを、”inputCrvShape”のcontrolPointsにコネクトします。
先程と逆にです。

先ほど完全に位置を合わせたので、translateをコネクトしてもカーブの形が崩れません。

これでコントローラーから髪の毛オブジェクトまでが繋がりました。
一度セーブして、コントローラを動かしてから再生してみましょう。
コントローラーの動きに髪の毛が付いてきて、かつシミュレーションが出来れば成功です。

●頭のジョイントについてくるようにする
ある程度、形になってきました。しかし、まだ問題があります。
頭に動きに髪の毛がついてきません。

コントローラーを頭の動きに追従させる必要がありますね。
空グループを作り”InputCrv_GP”と名付け、頭の骨”head_JT”とparentConstraintします。
そしてコントローラーを”InputCrv_GP”の中に入れます。

※(さきほど、Constraintは重くなると書きましたが、それは何千個も増えた場合です。)
※(ジョイントの直下に入れてしまうやり方も間違ってはないのですが、込み入ってくると整理が付かなくなります。
DFセットアップ室的には良しとされていません)

実際に頭の骨”head_JT”だけ選んで、移動してみます。

失敗です。
コントローラーはついてきてますが、肝心の髪の毛がついてきません。
何故でしょう。
先程コントローラーのTranslateをコネクションしましたが、これはlocal値を取得しています。
親をどれだけ動かしても子のTranslate値は変わりません。
world値を取得しないといけません。

pointConstraintを使いたいですが、前述したとおり重くなるので使いませんし、そもそもカーブの頂点には出来ません。
そこで、matrix系のUtilityノードを使います。

matrix系のUtilityノードは、事前にmatrixNodesプラグインが読み込まれている必用があります。
もし読み込まれていなかったらPlug-in Managerで読み込んでおきましょう。
Window > Settings/Preferences > Plug-in Manager > matrixNodes.mllのLoadedにチェック

Node Editorを立ち上げてコントローラーとカーブのコネクションを表示します。
Tabキーを押して’deco’と入力して”decomposeMatrix”ノードをコントローラー分作ります。

次にコントローラーの”WorldMatrix”をdecoposeMatrixの”inputMatrix”につないでいきます。

次にdecoposeMatrixの’Output Translate’を、カーブの各頂点”ControlPoints”につないでいきます。

これでずれていた髪の毛の位置がバッチリ合いました。

matirix系のUtilityノードは軽く、コントローラーとカーブ間を1つのノードだけで繋ぐことが出来ました。

●コントローラーの初期値を0にする
もう少しで完成です。
コントローラーのTranslateの初期値が問題です。
現在の値はとても覚えやすい値とはいえません。
毎回Ctrl+Zで戻すとか、全ての値をメモしておくのは、ちょっと実作業ではしたくないですね。

そこで同じ位置にグループを作り、親にしてしまいます。

これで、どれだけ動かしてもすぐに初期位置に戻せます。

●スプラインIKジョイントを頭の動きに追従させる
コントローラーからスプラインIKのジョイントの位置は制御出来ています。
しかし軸がこのままだと頭についてきません。
今回のサンプルはフサの形では分かりづらいですが、頭の上で髪の毛がくるくる回転してしまいます。
これはスプラインIKジョイントである”hairCrv1JT”を、頭に追従する”InputCrv_GP”の子供にすることで解決します。

●実際に動かしてみる
ちゃんとできているか実際に動かしてみます。
テストする為にフレームレンジを増やしてから再生します。

Dynamics > Solvers > Interactive Playback
これで再生すると、オペレーションしながら再生が出来ます。

最後の工程の前にキャプチャーしたものなので、スプラインIKジョイントの軸が安定していません。ご了承ください。

●まとめ
これで1本の髪の毛がセットアップされました。
今回は「ノード数が膨大になるので軽くなるにはどうするか」という部分がポイントです。
現時点での自分のやり方なので、もっと効率的なやり方もたくさんあるでしょう。
次回は、今回の処理を複数本の髪の毛にかける為、スクリプト化していきます。

●おまけ
ところで、Hairといえば、DFでは「rtHair」という高速な Hair Simulation が可能となる自社のmayaプラグインがあります。

開発部の方々が作ったもので、最近実戦投入されました。
実際に高速化を実現し、なかなかの成果を上げてもらいました。
速さの違いを動画でごらんください。

3倍ぐらい早いでしょうか。
髪の毛の動きは初期値そのままです。
当然、値を変えて動き方を調整できます。

Hairシステム自体の重さは、リグをどう組んでも解決できませんから、「rtHair」があると助かります。

この動画の髪の毛セットアップも仕組みとしては、今回説明したものとほぼ同じです。

この「おまけ」はノウハウとかではなく「DFでこんなことやってます」という紹介です。
また機会があればセットアップ中に役に立ったインハウスのプラグインを紹介したいですね。
紹介だけじゃ我慢できない、実際にさわって見たい方、DFの募集要項のページを一度ご覧になってみてはどうでしょう??
それでは、またお目にかかれたら幸いです。お疲れ様でした。

DFセットアップ室では、リギングアーティストを大募集中です。
一緒に魅力的な作品を作っていきましょう!
詳しくは、下記の募集要項をご覧ください。
https://www.dfx.co.jp/careers/designer/rigging-artist.html


※免責事項※
本記事内で公開している全ての手法・コードの有用性、安全性について、当方は一切の保証を与えるものではありません。
これらのコードを使用したことによって引き起こる直接的、間接的な損害に対し、当方は一切責任を負うものではありません。
自己責任でご使用ください。

Pocket

コメント

コメントはありません

コメントフォーム

コメントは承認制ですので、即時に反映されません。ご了承ください。

*