3Dグラフィックスの基礎知識

概要

シェーダーを書く以前に、どうやって動いているのかの知識がなかったので勉強した。 まだ実際に触っていない知識も多いので間違っているかもしれない。

シェーダーとは何か?

GPUで実行されるプログラム。レンダリングパイプラインの処理の一部。

レンダリングパイプラインとは?

3Dグラフィックスのプログラムが画面の描画(レンダリング)を行う際の、一連の処理のこと。 3D空間上にどのような形状の物が置いてあるか、カメラはどこにあるか、光はどこから当たっているかなどの情報を与えることで、 最終的にモニター画面に表示するような2Dの画面を作ることができる。

レンダリングパイプラインで実行される処理

1. 3Dモデルの情報を用意

入力となる情報を用意する。3Dモデルの情報とは、主に形状(ポリゴンの情報)と、置いてある座標のことを指す。 Unityで言えば〇〇レンダラーというコンポーネントが付いたオブジェクトをヒエラルキー上に配置すること。

2. 頂点処理(頂点シェーダー)

※ここからはGPUが実行する GPUはCPUに比べ、Inputが異なる同じ処理を並列に実行することが得意  これ以降の処理でInputとなる頂点やピクセルへの処理はまさにそのような並列処理だらけなのでGPUで実行  (そもそもGPUレンダリングでのCPUの不足を補うために作られたので、得意なのは当然)

頂点シェーダーの処理は主に二つある。 1つは座標形をローカル座標系からワールド座標系へと変換すること。(ここの詳細は省略) もう1つは頂点単位の陰影処理を実行すること。 3D空間上には光源となる物体が存在しており、そこから受ける光を表現して明るくしたり影をつける必要がある。 ポリゴンの法線ベクトルを用いて陰影の具合(光がどの程度当たっているか)を計算し、結果をポリゴンの頂点に格納する。 (頂点には自分がどんな色かという情報がもともと入っているため、陰影の具合でそれを加工する)

3. テッセレーション

ポリゴンの分割や形状変更ができる。比較的新しい機能で、ローポリとハイポリを場面によって使い分けるLODシステムに使われる。

4. ジオメトリシェーダー

頂点の増減ができる。ポリゴンは頂点からできているので、ポリゴンを増やすことにもなる。 (1で用意した情報を勝手に変えることができる) 細かい毛など、モデリングが手間なものをシェーダーで作ってしまおうという用途だと思うが、ちゃんとした応用例を調べれていないので詳細は不明。 1つ目のテッセレーションもそうだが、これがなければ動かないというものではない。(PS2時代くらいの昔はなかった)

5. カメラ空間への展開&クリッピング

これまでは3D空間に存在する全てのポリゴンに対して処理を行なったが、実際には画面に表示するのはカメラに写っているのものだけとなる。 そのカメラに映る範囲=カメラ空間であり、カメラの位置や向きから空間内にいるポリゴンの一覧を見つける。(カメラから見て「裏」になっているポリゴンは対象外とする) そのあとは不要なポリゴンの情報は捨て、中途半端なもの(ポリゴンの一部だけが範囲内)はポリゴンを分割する(クリッピング)。

6. ラスタライズ処理

残ったポリゴンが、カメラから見た視点(2D)ではどこに位置するのかを計算する(2Dのピクセル情報に紐づける)。 この処理と5の処理はあまり改善やセッティングの余地がなく、勝手に実行されるイメージ。

7.ピクセルシェーダー

ここが一番処理負荷が大きい部分であり、また色々とカスタマイズ可能な部分。 シェーダーと言った時はたいてい頂点シェーダーかピクセルシェーダーのことを指す、らしい。 主な処理は頂点シェーダーと同じく陰影の処理と、テクスチャの処理。 陰影の処理はピクセル単位のため、頂点シェーダーよりもなだらかな陰影や綺麗なハイライトが出せるらしい。(Per Pixel Lighting)

8. レンダーバックエンド

深度テスト(複数の描画対象物が同じピクセルにいる場合に、どっちを前にするか?を決める)と、 アルファテスト(透明度の判定)を行う。 ポストプロセスもここで実行する。

補足情報

レンダリングパイプラインで実行される処理は世代やGPUによって異なる場合がある。 また最近はここで書いた手法とは異なるレンダリング方法として、レイトレーシングというものが注目されている。 レイトレーシングはより現実に近い光の表現ができるが、処理がとても重いため、ゲームなどのリアルタイム処理ではまだ実用はできていないが、 CG作成などでは使われているらしい。

参考になった本

www.amazon.co.jp

www.amazon.co.jp

感想、今後

すごく簡単で全て文のため自分の見直しにしか役に立たなさそうだが、一通り理解できたことを確認できた。 原理が分かってスッキリしたので、今後は実際にどうシェーダープログラムを書くのかを勉強したい。