3Dのアニメーションでは手書きで見られるようなダイナミックな誇張を再現するのに
カメラ方向に大きく腕を伸ばしたりといったことも行われます
今までも色々な方法が使われてきた手法ですが、ジオメトリノードを使うことで
より細かく 色々なコントロールができるので検証してみます
因みにBlenderにおいてジオメトリノードはモディファイアとして機能するので
上の動画のようなアーマチュアの他、シミュレーションで動かしたメッシュの見た目を制御するといったこともできます
Blenderのカメラ座標
Blenderのカメラの座標は カメラから見て右がX上がY 奥行は手前方向にZとなっていて
オブジェクトとして回転が0の状態では カメラが真下を向く座標となっています
この座標軸に沿った方向にオブジェクトを変更できれば カメラからの見た目を制御できることになります。
まずはメッシュ全てをカメラ方向に平行移動してみます
「オブジェクト情報」で使用しているカメラの回転情報を取得して Z方向のベクトルを回転させるこどで
カメラ方向へ移動するベクトルを得ています。
オブジェクト情報のトランスフォーム空間の設定は「相対」に設定しておいてください
同様に [1, 0, 0]や[0, 1, 0]のベクトルを カメラオブジェクトの回転を利用して回転することで
カメラ基準でのX方向やY方向の移動に必要な単位ベクトルを得られます
距離に応じた変形
トランスフォーム空間を「相対」にしたオブジェクト情報の「位置」で取得できる値は
ジオメトリノードを使用しているオブジェクトと 指定しているオブジェクトの原点の相対位置です
各頂点の座標との差で 指定オブジェクトから見た各頂点の位置ベクトルを取得することができます
この位置ベクトルと さきほどのカメラのZベクトルとの内積で カメラ座標のZ値を取得できます
「範囲マッピング」を使って「一定のZよりZ値が小さい(カメラに近い)ほど移動量が大きい」ようにすると…
伸びた感じになりましたね
XYでの補正
カメラから見たZ方向で伸ばすのみだと オブジェクトがカメラから外れやすくなります。
カメラ座標のXYでの移動量を足します
画面内に収めるよう調整できるようになりました
ノードの整理
これまでのノードの計算をまとめて ジオメトリノードとして使いやすいよう整理します
また 頂点グループで影響を制御できるようにしました
スイッチノードの部分は 頂点グループ名を指定していない場合にはこれまで通りの値にするための処理です
キャプチャの一番右の人形の腕だけにウエイトを割り当てています
真ん中では顔が伸びているものが 伸びていないのが分かるでしょうか
グループ入力のノードは複数配置することができるので リンクの線を伸ばすのではなく散らして配置しています
さいごに
ここまでの解説のノードには入れませんでしたが
上記のものとよく似た計算で カメラからの見た目の平行移動ができます
また、今回と違った計算で、伸ばすのではなく 近づくほどオブジェクトが大きくなるといった実装もできます
色々試してみてください。
今回の解説ではmixamo からダウンロードしたFBXモデルを利用しましたが
デフォルト設定でインポートすると 親のアーマチュアオブジェクトに0.01のスケールが入った状態になり
変形のかかり方も100分の1になります。
この記事ではそれは考慮に入れず、スケールを適用したモデルで解説しました。
因みに途中から範囲マッピングの補完方法を SmoothStep変更していますが
SmoothStep にすると効果のかかる境界が滑らかになって変形の違和感が出づらくなります
SmoothStepの変換のグラフを図示すると右側のオレンジの曲線のようになります