続き。
長らく時間が開いてしまったけど、射影の話。
視点の生む空間
まず棲む空間をとりあえずおいてみる: としよう。ここで考えたい問題は、「一人称視点とは何か?」である。 視点としてある点 をとってみよう。とは言えどんな をとったとしても、空間全体を平行移動してしまえばそれは であったことと同じである。
この は の原点という意味である。同じ文字が違う物を表すことは多々あるので慣れるのをおすすめする。多くの場合は文脈を以って同一視できるものである。
さて、「視点から見える風景」の棲む空間は何だろう? だろうか?明らかにそうではない。視点は主観的概念であるが故に、客観よりも情報が欠落していると考えられるのが直観である。 実のところ「同じ視線上にある2点を区別できない」という非常に重要な特徴が存在する。これこそが視点の特異さである。
そうすると、この空間は本来の空間よりも幾分潰れていることがわかる。具体的には、任意の点 に対して である。が、ここで の範囲について注意しなければならない。
拡大縮小で移り変わるという意味では で良いのだが、今回は のとき原点にたどり着いてしまう。これでは となって空間全体が虚無に引きずり込まれてしまう上、「視界には視点は映らない」という性質を考えるにふさわしくない。 そして になってしまうと逆向きの世界を観測できてしまう。視線は原点を通らない半直線であり、条件としては がふさわしいわけである。これを空間の形で書くと である。
この表記は所詮習慣による記号なのでそのまま覚えればよい。 ちなみに純粋数学における 射影空間 (Projective space) という概念は で割る。つまり逆向きの世界すら同一視し、半直線ではなく「直線の成す空間」を考える世界である。
さて、結局どんな空間が構成されたかを考えてみると、 から原点を抜いて 、そして正の拡縮で割って となった。 実は私達はこの空間の別名を知っている。原点を除いたユークリッド空間の各点は長さを1に「正規化」することができた。この操作はもはや値を変えないから、全ての点の長さが1であると考えてよい。 だからこの空間は「長さが1の点の集まり」で出来ている。そして長さが1の点はこの空間に属している。つまるところこれは である。
これは私達の視界が2次元である、ということの表現にもなっている。ある視点からの風景は 上の画像で確定するのである。だから360°動画は を表現するために 、即ち経度と緯度という2次元の空間形状を使っている。
尚、人間の視点は2つある。視差によって空間情報を不完全ながらに復元しているのが人間の視覚である。
現実的投影
さて、理想的視点の場合の風景はわかったが、現実では多くの場合「モニタ」に投影される。 とは幾分異なる形状なわけだが、対象が平面の一部であるから線形空間としての扱いがやりやすい。
これは仮想的に の一部分であると考えることができるが、視線方向という要素が加わっている。具体的に投影について考えてみよう。 任意の視点と視点方向は平行移動と回転によって合わせられるため、ここでは視点が で視線方向を だとしても良い。なおこれだけでは画面の回転方向の自由度が潰れていないことに注意。 視点方向がモニタの向きなので、モニタは の平面にあると考えればよい。ここで である。
さて、視界という空間においては任意の点 に対して は等しい点であるわけだが、 その中には「モニタに載った点」も存在している。それが 、即ち の場合である。 結果的に となれば正しく2次元である。これを使えばモニタ上の点の位置が計算できるようになるわけである。
この領域の上では本来の長さが意味を持たないことに注意。だから遠いものが小さくなったり、その逆も起こりうるわけである。3Dゲームで視界の端が引き伸ばされて見えるのはモニタが平面だからである。
残念ながらこの操作は線形ではないから、全てを線形空間で扱おうとすることはできない。でも線形から離れてしまうのは最後の「割る操作」、射影 (Projection) だけである。実際元の空間で直線だったものは射影しても直線であることが知られており、誰かが射影さえしてくれれば私達は線形で考えてよくなるわけである。射影はそこそこ性質がいい。
これをやってくれるのが fragment shader の直前のGPUの働きである。
ちなみに、実際の3Dレンダリングの場合は遮蔽を再現するためのZ-Bufferが必要となり、空間を完全に潰すことができない。各頂点が出力する4次元の頂点情報の3つ目がこれであり、残りの1,2,4個目が今までの にあたる。