カメラのまとめ

# はじめに

しゃんぺんです。  
こんにちは。  

3Dのシーンを作るときには必ずカメラを使うことになりますが、カメラの操作方法って最初のとっかかりだけ教わり、そのあとは手探りで進むことが多い気がするのです。
オペレータスニペットも内容少ないし。。

これまで色々なチュートリアルやワークショップで教わった内容ではありますが、まとまっていると初学者の方に喜んでもらえるような気がしたので、まとめてみました。

サンプルファイルは[こちら](https://github.com/thinpedelica/camera_comp_test)。

なお、Bileam様のチュートリアルが大変有益なので置いておきます。
[Animating Camera Movement](https://www.youtube.com/watch?v=qKkcYwiqT_g)
[Camera Blending](https://www.youtube.com/watch?v=6Md4s5l07sY)


# 目次
- CameraCompの基本セットアップ
- よく使うパラメータ
- Compの連結(Parent)
- カメラ位置の移動方法
  - 手で動かす
  - chopでパラメタを変化させる
  - pathをsopで作る
  - CameraBlendCompを使う
  - ObjectChopでスイッチする
- Look Atのあれこれ
- ステップアップに向けて


# CameraCompの基本セットアップ

基本セットアップはすごく簡単。
- CameraCompを置く
- RenderTopを置く
- RenderTopにCameraCompを指定する

![1_base_setup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/61868387-eef2-9a65-991e-28d9cf597235.png)


CameraCompの初期値は、以下のようになっています。  
(TouchDesignerはY-upの右手座標系です)
- カメラ位置の座標：[0, 0, 5]
- カメラの向き：-z方向(原点を向いています)

さぁ、ここから思い通りのシーンを作るためにカメラを操作していこう！
と思うと、なんだか色々と苦労するんですよね。

順番にポイントを押さえていきましょう。


# よく使うパラメータ

パラメータの説明は[公式](https://docs.derivative.ca/index.php?title=Camera_COMP)を読むべしなのですが、まずはこれだけは知っておくとよさそうなものをピックアップしてみました。  

## Xform
  - Translate : カメラの位置を動かします！
  - Rotate : カメラを回します！
  - Look At : カメラの向きを指定したCompの中心に向けます
  - Path SOP : カメラの位置を指定したSOPに沿って動かせます。位置はPosition(0.0～1.0)で指定します

## View
  - FOV Angle：視野角を変更できます


# Compの連結(Parent)

カメラ位置の移動方法を説明する前にもう一つ。

CameraCompは、ノードの上部・下部にもポートがあり、コネクタをのばして他のCompとつなげることができます。上側になるノードを親:Parentと表現するそうです。  

子ノードは、位置や回転の量を親ノードから引継ぎます。つまり、子ノードの最終的な位置・回転は、「親ノードの位置・回転+子ノードの位置・回転」になります。

この親子関係を利用して、以下のようにセットアップするとよいそうです。
  - 親ノード：NullComp
  - 子ノード：CameraComp

![2_parent.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/ea398762-dac6-d473-7119-29c3c3db0404.png)



それぞれの役割としては、FOVなどのカメラの諸元はCameraCompで設定し、移動・回転はNullCompで行うと行儀が良い、と偉い人たちから聞きました。


# カメラ位置の移動方法

では準備が整ったので、カメラ位置を色々な方法で動かしてみましょう。

## 手で動かす

CameraCompのViewerや、GeometryViewer上でのマウス操作でカメラの位置を操作できます。  
シーンを確認しながらカメラの基本位置を探るのに良いんじゃないかと思います。

- CameraComp
  - ViewerActiveを押す
  - 手で動かす

![4_viwer_active.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/8dfc6f7f-1115-5dcb-ca55-1f42f5ebf3a6.png)



- GeometryViewer
  - Camerasからカメラを選択する
  - 右のロックボタンを押す
  - 手でカメラ位置を動かす

![5_geo_viewer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/c9fb8104-69fc-5256-169e-d7666642945e.png)



マウスの操作方法は以下のとおりです。
- 左ドラッグ: 回転
- 右ドラッグ: 平行移動
- 中ドラッグ: ズーム

## chopでパラメタを変化させる

シンプルに左右にパンしたり、ズームイン/アウトしたり、音楽に合わせて激しく動かしてみたり。

chopの値をパラメータに設定するときは、比嘉さんのワークショップで教わった方法が便利です。
1. チャネル名をリネームして、cam1:txのように「設定先ノード名:」を付与する
2. Common.ExportMethodをChannel Name is Path:Parameterにする
3. Exportをonにする

![6_chop_export.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/fb075c3f-ac0f-9e77-fe41-c3edbeb9ec04.png)



chopでカメラを操作する具体例は、森岡先生がとても有益なテキストを書いてくださっているので、ぜひそちらを読んでみてください。
[ラインとそれをフォローするカメラ](https://note.com/toyoshimorioka/n/n8bc9e97fd635)


## カメラの軌道(path)をsopで作る

TouchDesignerをはじめて最初の頃にこの機能を知って、直感的で分かり易くて、すごく感激した記憶があります。懐かしいですね。

一応手順を書きます。
1. カメラの軌道となるSopを作る
2. CompのXform.PathSopに1.のSopを参照させる
3. CompのXform.Positionの値を変化させる

PathSopとPositionは、CameraCompだけでなくNullCompにもあるので、前述の親子関係を組んだNullComp側で動かすこともできます。

![7_path_sop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/a9d648b2-2874-56f1-aeed-0387a1a2eaf7.png)



カメラの方向はlook atでターゲットの方向を向かせるか、進行方向を向かせることが多いかと思います。
進行方向に向かせる方法は以下のテキスト・チュートリアルで紹介されています。

[トンネルループを作る](https://note.com/toyoshimorioka/n/n044e6b23cad7)
[Looping Noise](https://www.youtube.com/watch?v=gJ6xok9cP_s)

## CameraBlendCompを使う

CameraBlendCompの上側のポートには、複数のCameraCompを接続することができます。  
こうして接続したCameraの位置を、CameraCompはブレンドしたり、補完しながら切り替えてくれます。

Blend.TypeでBlendを選んだら、接続しているカメラの位置をブレンドしたカメラ位置を作ってくれます。
ブレンド具合は、Weightに指定する数値で変更できます。
と言いつつ、僕はCameraBlendCompでBlendを使ったことは無いです。
(ブレンドで良い具合のカメラ位置を作れるんかな。。)

Blend.TypeでSequenceを選んだら、接続しているカメラの位置に順番に切り替えてくれます。
Blend.Sequenceは0なら最初に接続しているカメラ位置、1なら2番目のカメラ、2なら3番目のカメラ、、といった具合です。0.0から1.0の間の数値だと1番目と2番目のカメラ位置を補完した位置を作ってくれるので、数値を変化させることでスムーズにカメラ位置を変化させることができます。
すご便利。

なお、RenderTopにはCameraBlendCompをそのまま指定することができます。
ですが、GeometryViewerにブレンドされた結果のCameraが描画されないため、僕はもう1回CameraCompにつなげてGeometryViewerで動きを確認して使っています。

![8_cam_blend.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/d6c010c5-785a-92b7-cd41-269fe7f0415f.png)



## ObjectChopでスイッチする

CameraBlendCompは便利なのですが、カメラを1番目から5番目に移動したいというなindexが飛ぶような動きができません(2～4番目のカメラ位置を経由してしまうため)。

できるだけ簡単になんとかならんかなってあれこれしたのがObjectChopを使った方法です。
Object CHOPは「2つのオブジェクトを比較して、絶対、あるいは相対的な位置と方向のチャンネルを出力」するchopだそうです(今回初めて知った)。

ObjectChopにCameraComp/CameraBlendCompだけ指定すると、Cameraの現在の位置・回転が簡単に取れます。
Chopに出来れば、LagChopを挟んでよしなにしてからまたCameraCompに戻せば、割と良い具合にスイッチできるようになりました。

![9_oject_chop1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/ba8b8d4f-b954-abc3-9c8e-f5ed48494de4.png)



上記の方法だとFOVが取り出せないのが難点です。
FOVも切り替えていくようであれば、CameraBlendを介さずに直接CameraCompから値をChopに取り出してSwitchすればええやんというのが次の作戦です。

![9_oject_chop2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/584dba70-fda4-e63d-b880-3db31f5e71a6.png)



僕はObjectChopで簡単に済ませてしまったのですが、偉い人のtoeを覗かせてもらったらprojection matrixとかを使うのが正道のようです。しかし僕には手に余るので割愛。正道へのリンクだけ置いておきます。
https://docs.derivative.ca/index.php?title=CameraCOMP_Class#Methods


## Look Atのあれこれ

Look AtにNullCompを参照させて、Nullの位置を向き続けるカメラワークはよくやると思います。  
ただ、カメラを移動させていると意図せぬ方向を向きだすことがあります。  
マニュアルを読んで注意点を整理しました。

### アップベクトルを使わない場合
Xform.LookAtUpVectorにUse Rollを指定するケースです。

マニュアルには以下のように注意事項が書いてあります。
「カメラ位置がターゲットのY軸を通過しない場合、このオプションを使用します。
Y軸を通過する際に、アニメーションがフリップする可能性があります。」

実際に試してみると、カメラ位置がNullCompのY軸と交わるときにカメラの向きがフリップしています。

![output_10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/006b7404-ee94-3f26-952b-34a9aa363cb8.gif)


### アップベクトルを使う場合
Xform.LookAtUpVectorにUse Up Vectorを指定するケースで、カメラの上方向をXform.OrientUpVectorで指定します。
デフォルトでは[0.0, 1.0, 0.0]で、いわゆる上方向になっています。

マニュアルには以下のように注意事項が書いてあります。
「指定されたアップベクトルは、ルックアット方向と平行であってはいけません。」

では試してみましょう。
アップベクトルとルックアット方向が平行(このサンプルではY軸方向)になるときにカメラの向きが計算できなくなっています。

![output_11.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880453/ebb3bb2a-7191-6a32-819d-6623f2a89dd3.gif)



# ステップアップに向けて
ここまででCameraCompの基本的な使い方をお伝え出来たかなと思います。
では、これで良い感じのカメラワークを作れるか、というと難しいんじゃないかと思います。

もともとカメラや映像をやっていない人にとっては、そもそも「良い感じのカメラワーク」が分からないんですよね。
僕もそのタイプだったのですが、今年の頭に敏腕カメラマン様にマンツーマンレッスンを受けるなど、色々と勉強する機会がありました。
勉強してみて有益だったと思ったことを共有します。

- カメラの仕組み
カメラの光学的な仕組みを学ぶと、パラメタの意味が理解できるようになるので良かったです。
(DoFの意味が理解できるようになりました)
[カメラとレンズのしくみがわかる光学入門](https://www.amazon.co.jp/dp/B07TK99XTH)

- カメラワーク
代表的なカメラワークを紹介するチュートリアルです。
カメラワークに悩んだ時の総当たりのおともに。
[Ultimate Guide to Camera Movement](https://www.youtube.com/watch?v=IiyBo-qLDeM)
上記以外のチュートリアルも敏腕カメラマン様オススメです。
[The Shot List](https://www.youtube.com/playlist?list=PLEzQZpmbzckV0_a2QCO2qF9Yfe-LKSDha)

- 構図
「構図といえば葛飾北斎」というのは有名なお話らしいです。
僕は知らなかったですが。
[北斎のデザイン](https://www.amazon.co.jp/dp/B08W521PHN)


# おわりに
TouchDesignerをモリモリ使っている人には既知のことばかりで若干申し訳ないですが、
僕自身が今年やってきた中で一つ選ぶとしたらカメラでした。

ちょうどLookAtのフリップする特異点で困っていて、改めてマニュアル読んだら書いてあるじゃん！ってなったこともあったので。

カメラの勉強をしてから、ふだん写真を撮るのも楽しくなりました。
来年はライトの勉強をしたいですね(フラグ)。

おしまい