ごめんなさい、仕事が忙しすぎて今頃の投稿になります…。
今回はカメラアニメーションにおけるちょっとした小ネタになります。
カメラを動かしてよりダイナミックな絵作りを
プログラムでジェネ系の映像を作ってるとき、オブジェクトばかりを動かしてカメラを動かさない絵をよく見かけるので、初心者はカメラを動かすことを覚えるといいよ、という提案です。
オブジェクトを動かす、とは
魅せたいオブジェクトが白のボックスだとしたら、だいたいまずはみなさんこいつを動かそうとします。
今回は単純なXZ平面に対する円運動と、オブジェクト自身がXとYにRotateしております。
だいたいクリエイティブコーディング系の環境だと
box.position.x = cos(time) * 500;
box.position.z = sin(time) * 500;
box.rotateY(0.01);
box.rotateX(0.01);
みたいなコードをUpdate関数で延々と呼び続けることでできるはずです。
しかしこの手の動きはどんなにいじってもだいたい眠くなりがち。
カメラを動かす、とは
カメラをグッと魅せたいオブジェクトへ持って行きます。
これで結構インパクトのある絵になってきました。
必要な概念は2つ。
- カメラ自身のposition
- カメラ自身が向いてる方向
です。これから詳しく説明していきます。
カメラと白いボックスの初期設定
カメラ自身が向いてる方向は、だいたい初期値ではvec3(0,0,0)になってると思います。
これはカメラが3Dワールドの中心を見ているということです。
今回この白いボックスはvec3(0,0,0)、つまり座標系の中心に置いています。
3Dワールドの中心で、白いボックスはくるくる回っています。
そして今回、カメラの初期の情報は以下の通りに設定しました。
camera.position.z = 500;
camera.position.y = 100;
camera.lookAt(vec3(0,0,0));
これは白いボックスより手前に500、上に100の位置にあるカメラが、3Dワールドの中心、つまり白いボックスを見つめている状態です。
ちなみにOpenGLの右手座標系のお話ですので、各自適当に置き換えてください。
そして動かす
カメラをグッと白いボックスへ寄せたい場合、カメラ自身はオブジェクトの手前で寸止めすればいいので
camera.position.z += (box.position.z+100 - camera.position.z)*0.1;
camera.position.y += (box.position.y+50 - camera.position.y)*0.1;
これは、boxのzより100手前、boxのyより50上の部分にグッとよるコードになります。
最初ははやく、目的地に近くなればなるほどゆっくりと進むeasingがかかっています。
重要なのはグッと寄って手前で止まる、ということです。
そして次にカメラの注視点を動かします。
lookat_x = sin(this.timer*0.8)*10;
lookat_y = cos(this.timer*2)*10;
camera.lookAt(vec3(lookat_x, lookat_y, 0));
これはつまりどういうことかというと、カメラの注視点が、x,yにそれぞれ -10 ~ 10 のあいだでゆらゆらしているということです。
カメラというのは、現実世界だと人間がもって動かす事が多いですよね。
スマホなんかで動画をとってるとき、カメラをズームしてみてください。
少しの手ブレでも絵が大きくうごきますよね?それを再現しています。
2Dのアニメーションなどでも、こういった演出はよく見られます。
以下のYoutube動画で参考になりそうなリンクを貼っておきました。
40秒あたりからカメラがグッとより、寄ったあとでカメラがゆらっと動く演出があります。ハースストーンのトレーラはどれもカメラワークの演出が素晴らしいので、色々見て参考にしてください。
余談
こんな感じで3Dワールド全体をグルッと回りながら、Z軸のsin運動を大きくとってみたり、少しy軸にゆらゆらずらしてみると奥行きが表現しやすかったりします。また与える時間軸もそれぞれの値ごとにずらしてみると、変化が増えて面白いです。
camera.position.z = sin(this.timer) * 100 + 200;
camera.position.y = sin(this.timer*2) * 100;
camera.position.x = cos(this.timer) * 500;
lookat_x = sin(this.timer*0.8)*10;
lookat_y = cos(this.timer*2)*10;
camera.lookAt(vec3(lookat_x, lookat_y, 0));
映像を作ってるとき、なんか眠いんだよなーと思ったときは、大胆にカメラを動かしてみるとよいかもしれません。
ただあんまり多用すると逆に酔ってしまうので、ほどほどにしましょう…。
今回はわかりやすく大きめの値を設定しておりますが、実際は少しの値の変化でも印象がガラッと変わってくれます!
ぜひ試してみてください!