« SARA3ケースでPCを組んでみる | トップページ | OpenGLいろいろ »

2015年8月30日 (日)

OpenGLのZの扱いについて考える

さて、GPUについて超基本的な勉強をしているところです。

  たとえばOpenGLの場合、3D-CGモデルで射影変換を行う場合の変換行列は、glFrustum なり gluPerspective なり、の中身の仕組みを理解しておく必要があるわけです。
 glFrustum は シフトレンズ を仮想した仮想カメラを置く場合なので、ひとまずシンプルな gluPerspective の中身を読み解いて見ます。

 

https://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml

  行列構造としては大雑把に

Glperspectivemat

  な形式をしています。
  1行目(X値の項)、2行目(Y値の項)のA,Bと4行目(斉次の項)の-1は、画角設定とZ距離に応じて縮小するという射影変換の基本的な話。それとZ軸が遠方に負の値をとるという座標系の置き方の問題だけなので、検索すれば日本語の説明も多いように思います。

 一方で、3列目(Z値の項)はなしてこげん式になると?

  ってことで理由を探すのが面倒そうだったので、独自に解釈して見ました。たぶんここだけプログラミングの問題じゃなくてハードウェアの作りやすさの問題が入っている気がします。

 まず、このままこの行列で座標を変換するとz値がどう変換されるかというと

 

Glperspective_1
となって
Glperspective_2

となるので

描画範囲である視点前方となる座標系方向( z < 0 )の領域に限定すれば、単純増加 or 単純減少の式になるわけです。

ここで、

   z = -zNear のとき  z' = -1
   z = -zFar   のとき  z' = +1

  となるように連立方程式を置いて C, D を 解くと、

Glperspective_3

Glperspective_4

  となり、OpenGL の glFrustum や gluPerspective のAPI説明と一致するわけです。

  このとき -1 < z' < +1 が表示範囲に入るわけです。

 ここで、-1 < z' < +1 が表示範囲 (abs(z') < 1)というのは浮動小数点表記としては、指数部だけで判定が出来るという点で、非常にハードウェア向きです。

  そして、分母に浮動小数点減算が入るので、値次第でZの精度が欠落(桁落ち)します。

  3D-CG プログラマにとって重要なのは、変換前の z が zNear  ~ zFar の範囲にあるときに描画されるという事実と、zNear にあまり 0 に近い値を入れると精度が悪くなるという事実だけなので、API説明にはここしか書かれておらず、なんでこんな行列式になってるのかあまりまじめに書かれていない気がしますが、たぶん上のようなハードウェア実装上の理由なんだろうなと想像しております。

  あと、もう一点ハードウェア実装を考える場合に重要なのは、z = 0 に3Dオブジェクトがくると、描画範囲外であるが0除算が起こりうるということです。

  描画範囲外とはいえ、適切に弾く仕組みは必要そうです。浮動小数点で、無限大やNaNに倒しておけばいいですが、うっかり0除算時に出力が0になるようなタコ実装をしてしまうと表示領域に入ってしまいます(固定小数点実装だとやりかねないかも)。

  ソフトウェア実装したときなんかも気をつけておかないと力いっぱい0除算例外で落ちたりします (^^;

« SARA3ケースでPCを組んでみる | トップページ | OpenGLいろいろ »

FPGA」カテゴリの記事

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: OpenGLのZの扱いについて考える:

« SARA3ケースでPCを組んでみる | トップページ | OpenGLいろいろ »