かなりふつう

ヾ( ゚д゚)ノ゙

【SlideCameraWork】理論を実装に変える話4

間が空いたけど、続き書くよ!


前回のおさらい。

・・・①

こういう式がありまして、これをグラフに描画すると


こうなるんでした。でも、これは入力するべきxが-6~+6で、使いづらい。
xの値域を0~1にして、適宜ゲインをかけて調整できるようにしたいってことでした。
ちなみに、こんな風に使いやすい値(1とか)で処理できるように改良することを
「正規化」と呼びます。正規化という言葉は意味がわかりにくく、難しい印象がありますが、
「~をまとめて1と考えると」などの思考は皆さん日常でも頻繁に使っていると思いますが、
それがまさに正規化です。鉛筆12本を1ダースとして処理するのも、一種の正規化です。


てことで、上の式を「正規化」して
  ・・・②

という式を作りました。これは要するに、zに0~1を入れたとき、①の式でxに
-6~+6を入れたときと同じ結果になるようにしようというのが目的でした。
xにその値域を入れるということは、-ax(eの指数)の結果は

※a=1とする
x=-6のとき、-ax=6
x=±0のとき、-ax=0
x=+6のとき、-ax=-6
です。
 では、zを入れてこうなってくれるでしょうか。

z=0のとき、eの指数=6
z=0.5のとき、eの指数=0
z=1のとき、eの指数=-6

ちゃんとできてますね。それじゃ、Yはどうなるんでしたっけ。

z=0(x=-6相当)のとき、Y=1/(1+e^6)=1/403.43 ≒ 0
z=0.5(x=0相当)のとき、Y=1/(1+e^0)=1/2=0.5
z=1(x=+6相当)のとき、Y=1/(1+e^-6) ≒ 1/1=1

はい。見事にzが0~1のとき、Yが0~1になっています。
ちなみに、これをEXCELでグラフに描いてみた結果がこちら。



 線が3本ありますが、これは今まで「a=1」と言ってきた、いわゆるゲインを
調節してみたものです。このaはeの指数全体に掛けるものなので、やっていることは
eの指数部分「6-12z」を「a*(6-12z)」としているだけです。最終的には、このaを
GTA内で調節することにより、こんな感じでカメラの加速の仕方をある程度調節
できるようにします。


 もう少し進めましょう。


 GTAは3Dですから、座標も当然X・Y・Zの3つがありますが、基本的には、
上にある式を3つの軸それぞれに同じように適用させて処理します。
 3軸別々のゲインを設定できるようにすればかなり柔軟なカメラワークが作れると
思いますが、その調整はイメージしにくく非常に面倒になることは間違いないので、
3軸独立ゲインは実装しないことにします。

 さて、それでは具体的にGTA上で話をしましょう。
 仮に、カメラワークを以下のように実行したいとします。

初期値(始点)
 X:2500.0
 Y:1300.0
 Z:20.0

目標値(終点)
 X:2550.0
 Y:1400.0
 Z:25.0

※ここでのXというのは、GTAの3D座標を示す変数です。これまでにやってきた計算式の
Xとは意味が違いますので注意してください。

 GTAでは、この座標の単位1が約1m程度のようなので、この動きはざっくりと言って
けっこう大きな動きです。Zも20から25なので、地上から屋根の高さくらいまで動くことを
意味します。まずはこれを、1000フレームで動かしてみようと思います。

 目標値まで動かすということは、初期値から、進んだフレーム分の変化量を足すという
ことです。0フレーム目であれば変化量は0ですから、初期値+0、つまり初期値と
同じ、要するにまだ全然動いていないということを示します。
 逆に1000フレーム目であれば、「終点-始点」をまるまる変化したわけですから、


 Xの変化量=2550-2500=50
 Yの変化量=1400-1300=100
 Zの変化量=25-20=5

となりますね。その変化量を初期値に足すので、変化した結果

 変化後のXの値=2500+50=2550
 変化後のYの値=1300+100=1400
 変化後のZの値=20+5=25
 

となります。当たり前ですね。ここまでは長々と書いてきた計算式なんて使う必要も
ありません。

 では、500フレーム動いたときはどうでしょうか?
 500フレームというのは、総フレーム、つまり1000フレームのうち、何%でしょう?
これは簡単です。500/1000=0.5=50%です。全体を1としたとき、0.5進んだ地点
ということです。

 さあ、出ましたよ。この0.5です。
 今まで色々計算式をいじってきました。その目的が「0~1で操作したい」ということ
でしたね。この0~1の値が、この「どのくらい進んだか」を意味するわけです。
つまり、500フレーム動いたときには、この動いた割合0.5を、式に代入して計算すれば
よいのです。

 まず、元々「変化する量」とはいくつでしたか?要するに、全部動かしたらどのくらい
でしょうか?それは③で出ていますね。そのうちの半分、0.5なんですから、
「0.5の変化に対して、実際に動く量はいくつか」ということを計算します。ここでいう
変化が、②のXに相当します。実際に動く量の割合が②式でのYです。実際に動く量の
割合が求まれば、「全部動かしたときの変化量」にその割合を掛け算することで、
「実際に動く量」が求められます。
 計算してみましょう。

動いた割合が0.5のとき、実際に変化する量に対する、変化するべき量の割合は

 変化するべき量の割合=1/(1+e^(6- 12 × 0.5))
            =1/(1+e^0)
            =1/(1+1)
            =0.5

となります。これに「実際に変化する総量」をかけると

 変化するべきX=50 × 0.5 = 25.0
 変化するべきY=100 × 0.5 = 50.0
 変化するべきZ=5 × 0.5 = 2.5

最終的に、500フレーム経過したときのカメラの座標は

 500F後のXの値=2500+25.0=2525.0
 500F後のYの値=1300+50.0=1350.0
 500F後のZの値=20+2.5=22.5
 

となりました。これが本当に求めたい答えです。
これが出れば、あとはプログラムコードを組むだけです。

とゆーことで、今までの流れを一般化してみましょう。


1、初期値(始点)を記録する
2、目標値(終点)を記録する
3、総変化量を求める(目標値-初期値)
4、総フレーム数を記録する
5、任意のフレームが総フレームのうちどのくらいか、その割合を計算する
6、求めた割合を計算式に当てはめ、実際に動く量の割合を求める
7、「総変化量 × 実際に動く量の割合」を計算し、「実際に動く量」を求める


という流れになります。これこそが「理論を実装に変えた」瞬間です。
ついに、あーだこーだ机上で述べてきた空論が、形を持って結果として出てきました。

ついでに、実際の計算も一般化しておきましょう。

1、ゲインをaとして代入しておく
2、始点をそれぞれ「bX,bY,bZ」とし、それぞれにXYZ値を代入する
3、終点をそれぞれ「eX,eY,eZ」とし、それぞれにXYZ値を代入する
4、総変化量を「dX,dY,dZ」とし、1と2から計算した結果を代入する
5、総フレーム数をtFとして、これに代入しておく
6、nフレーム目のtFに対する割合をrFとし、計算して代入する

  このとき、rFは
  rF = n / tF

7、実際に動く量を「ΔX,ΔY,ΔZ」として、計算して代入する

  このとき、7の値は
  ΔX = dX /(1+e^(a×(6-12 × rF)))
  ΔY = dY /(1+e^(a×(6-12 × rF)))
  ΔZ = dZ /(1+e^(a×(6-12 × rF)))

8、nフレーム目のカメラ座標を「rX,rY,rZ」として、結果を代入する

  このとき、8の結果は
  rX = bX + ΔX
  rY = bY + ΔY
  rZ = bZ + ΔZ



はい!できましたー!
このrX,rY,rZが、nフレーム目におけるカメラ座標となるわけです。
GTAは変数に名前を付けられない上に、わずか31個しか使用できないのでこの記事の
ように分かりやすいまま実装することはできませんが、なんとかうまくコーディング
すれば同じ処理を実現できます。


ということで、あとはプログラムの話になりますので以降は割愛。
割愛しないと、何百行ものコードを記事に羅列するだけで、
誰も、どころか自分もわからないと思うので。

 こんな感じで、1つ1つ目標に向かって適切に考えて、しっかり理論と数式を結び付けて
いくことで、プログラムコードという実装へ落とし込むことができます。最初は何を
やっていて、どこを目指しているのかわからなくなることも多いと思いますが、その時は
素直に一旦諦めて棚上げしてしまった方がいいです。もっと小型の、シンプルなアイデアを
形にすることを何度か実践して練習し、その流れを身体で覚えた方がいいでしょう。
たとえば、今回のようにカメラワークのエンジンそのものを作ろうとすると、今が
どうなっていて、何が不便で、どうすれば改善できて、そのためには何が必要で、
どれだけ複雑なのか、ちゃんと把握できていないとパンクしてしまいます。今回の
改良も、これまでのSlideCameraWorkという実績があるからこそスムーズに行えたもの
なんだということを知っておいてください。

 本当の最初は、確か何かキーを押すと今の視点で固定されるだけ、という極めて
シンプルなものだった気がします。そこから、カメラを動かすコードの存在を知り、
でも2つのコードがセットになっていて、試行錯誤しながら動作を覚えていき、
カメラを移動させる方法を考えたけれども満足できず、もしかして、ものすごく細かく
瞬間移動カメラを連続実行させれば、滑らかなカメラワークとして機能するんじゃないかと
思ったらうまくいって、そこから始点と終点を決定するためのインタフェース作りに
悩んで、変数が多すぎて大混乱の中でメモリ操作を覚えて、そしてカメラの回転なども
改良に改良を重ねて、そして現在のSlideCameraWorkがあるという感じです。Pixivだったら
評価点100点ももらえないような子供のおもちゃレベルのものからのスタートだった
わけです。なんとかなるものですね。

 なのでこれが実装へ漕ぎつくための唯一のやり方ではありません。しかし、いい加減な
ところがあってはそこから先へは進まないということは分かってもらえたと思います。
漠然としたやる気だけで事に臨まず、堅実に着実に、真剣に取り組んで作ってみて下さい。
ちょっとずつだけどよくなっていき、次第にできることが広がっていくと思います。


以上、また何かあったらそのときに。
この新しいエンジンを積んだSlideCameraWorkは、なるべく早く公開まで持っていきたいと
思います・・・。がんばる。



.

Comment

Form

お名前
タイトル
E-MAIL
URL
コメント
パスワード

カウんター

カウンター

プロフィール

普通のげーまー
ニコニコ動画で「東方姫一華」連載中です

最新コメント

[03/11 Dof]
[03/09 普通のげーまー]
[03/04 Dof]
[03/04 普通のげーまー]
[03/04 普通のげーまー]

ブログ内検索

管理用

TemplateDesign by KARMA7