2012年07月26日

ラスタライズとZバッファ法について

車輪の再発明ですが、ラスタライズとZバッファ法を試してみました。

レンダリングを行う場合、以下の手順で行います。

ワールド座標系→視点座標系→正規化座標系→スクリーン座標系?

→の部分は、4x4のアフィン変換行列を掛ければできます。

まずは、ワールド座標系から視点座標系に変換する行列は、カメラの位置と向きを決めれば、カメラから見た座標系に変換するためのビュー行列を計算することができます。

次に、正規化座標系ということで、X,Y,Zそれぞれ[-1,1]の範囲に収まるように変換するプロジェクション行列が必要です。これも、視錐台の空間を[-1,1]の範囲に行列を掛けることで変換する方法ですので、視野角、アスペクト比、近/遠クリップ面までの距離が決まれば、プロジェクション行列を計算できます。

アフィン変換行列は合成ができますので、ビュー行列にプロジェクション行列を掛けたものが、ワールド座標から正規化座標へ変換するための行列になります。

この行列が求まれば、三角形の3頂点をワールド座標から正規化座標に変換できます。
(同次座標系で考えていますので、wで割る必要があります)

このあたりの行列の計算方法は、[1]を参考にさせていただいております。

画像のサイズが640×480であれば、正規化座標系からスクリーン座標系に変換するために、[-1,1]を[0,1]の範囲に変換して、その後640や480を掛ければ、画像のピクセル座標が求まります。

ラスタライズは、この求まったスクリーン座標系の3頂点を、スキャンラインで描画画素を辿っていく方法です[2]。
今回は、ポリゴンが横一直線上にある場合、3頂点のうち2頂点が同じY座標を持つ場合、3頂点ともY座標が異なる場合で場合分けしまして、3頂点ともY座標が異なる場合は、[2]を参考にして上半分のポリゴンと下半分のポリゴンに分割してラスタライズしました。

Zバッファ法は、隠面消去のための方法で、ピクセル座標の現在の深度値と3頂点の深度値から得られる深度値を比較して、より手前にあれば深度値を更新する方法です。

以上のような手順ですが、GPUなら高速に大量のポリゴンを処理してくれますので、OpenGL等が使えないような特殊な環境でないとやる意味は殆どないと思います。
ただ、アフィン変換行列を使って最終的な画像の位置と深度値を求めていくことができますので、線形代数やCGの勉強にはなるかもしれません。

実行結果

座標手打ちの立方体(12枚の三角ポリゴン)を上記の方法でレンダリングした結果です。

rasterize_001.png

一応アンチエイリアスもやっていますが、カクッとなっているところがあるのでバグがありそうです。
自動でやってくれることを自分でやろうとすると面倒な上に結果が微妙ですね。

参考文献
[1] http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20090821
[2] http://www.mm.media.kyoto-u.ac.jp/members/kameda/lecture/le4cg/html/node13.html
posted by シンドラー at 00:12 | Comment(0) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック