リアルタイムレンダリング最初から その1

次世代機も出たタイミングで自分自身の知識の整理も兼ねて、レンダリング手法について何回かに分けてなるべくわかりやすくまとめてみます。


f:id:IARIKE:20140223233139j:plain

1.何もない世界

 ゲームの世界には何も存在していませんので、何も見えません。
真っ黒なディスプレイが表示されています。

2.二次元ワイヤーフレーム

 二次元空間上(x,y)に定義された2点(二次元ベクトル)を結ぶ線で、立方体が表示されています。
線は見えるので、一応そこに物体が存在することはわかりますが、座標は二次元しか持たないので
ただの四角形にしか見えません。

3.三次元ワイヤーフレーム

 三次元空間上(x,y,z)に定義された2点(三次元ベクトル)を結ぶ線で立方体が表示されます。
点は(x,y,z)の情報を持ちますが、画面は二次元なので、三次元=>二次元に変換する必要があります。
 三次元=>二次元への変換は、透視投影行列によって行われます。
(行列は点(ベクトル)を移動させたり、次元を減らしたりする便利な道具と考えて下さい)

 この透視投影行列により、三次元は二次元に変換され、ディスプレイに表示されます。
 奥にある線は小さく表示されるため、奥行き感はわかります。が、立方体の奥の線(後ろ側の線)が見えているのは本来おかしいですね。現実なら手前の面に遮られます。

4.隠線処理

 立方体の手前の面に遮られた線は、本来見えていてはおかしいです。
本来見えないはずの線を削除することを、隠線処理といいます。
 これでやっと立体ぽくなりましたけど、正直ただの線です。








f:id:IARIKE:20140223233144j:plain

5.ポリゴンとラスタライズ

 今までは線だけでしたが、立方体の色を塗りたいと思った時、面が必要になります。
ポリゴンは三次元空間上に定義された3点を結んだ三角形(=面)です。

 実は線の時もそうだったのですが、二次元空間上に定義された点や線をそのまま画面に表示することは出来ません。変換が必要になります。
 画面は小さなピクセルの集合で構成されているため、画面に表示させるためには
どのピクセルに何色を表示させるか、を決める必要があります。
(ピクセルの座標も(x,y)の二次元で指定しますが、値は整数値しか入りません。上から○個目のピクセル、という指定をするためです。)

 この二次元空間から画面のピクセルに変換する処理をラスタライズといいます。
変換前の情報はベクトル(ベクター)で、変換後はラスターになるので、ラスタライズってことですねきっと。
 あとは面の色(緑)を決めるだけで色が付きます。

6.曲面

 立方体だけではつまらないので、球体を表示させてみます。
球体はぱっと見では滑らかですが、よく見ると細かいポリゴンが集まったものであることがわかります。
 これで分かるように、ポリゴンさえあればこの世の中の全てのものを表現することが出来ます。
ポリゴン最高!でも単色だと円にしか見えませんね。

7.ライトとシェーディング

 ポリゴン的には球体なのに、円にしか見えないのは困ります。
 そういえばレンダリングに重要な要素であるライト(光源)を忘れていました。
光源を置くと図のように球体に見えます。

 さて光源を置いたからといって勝手に明るくなったり暗くなったりするわけではありません。
計算が必要になります。(いわゆる光源処理と呼ばれるもの)
 図の右を見てもらうと分かる通り、光源に対して正面を向いている面は沢山の光を受け取るため明るく、面が傾いていくにつれて光の当たる量が減り、ついには一番右の面のように真っ暗になります。

 これを計算式で表すと…

Id = (N・L) = |N||L|cosθ

 になります。さぁいきなり難しくなりました!!!!!(高校レベル)

 ここでIdは求めたい面の明るさ、Nは面の法線、Lはライトのある方向(ライトベクトル)です。
法線(NormalVector)とは面の向きを指定するベクトルのことで、図の右に書いてある矢印Nがそれです。ライトベクトルLも、右上の面は描いてありますね。

 さて、N・Lは掛け算でもなんでもなく、ベクトルの内積という計算です。
内積を用いるとベクトルの間の角度を計算でき、それがそのまま面の明るさになっているわけです。この計算のことをランバート反射といいます。

 この公式が言っているのは、面の向きと、そこからライトへの向きさえ分かれば面の明るさを計算出来るっていうことです。
たった二つのベクトル(6つの数字)でそんなことが計算出来るなんて、実はそんな難しくないんじゃね?って気もします。

GPU的には

 これまでの処理をGPUのどこが行っているのか見ていきます。

1.透視投影行列により、ポリゴンの各頂点を三次元=>二次元にする処理を行っているのは頂点シェーダ(VertexShader)です。

2.ラスタライズを行うのはラスタライザです。ここはプログラマが弄れないところです。

3.ラスタライズによってピクセルに分割された後、光源処理を行いピクセルに色を付けるのがピクセルシェーダ(PixelShader)です。

出てきた数学

 今のところベクトル(+内積)と行列、三角関数(cos)ですね。
やはりこれらの知識は必須になります。