12. デプスバッファ

12.010 デプスバッファを機能させるにはどうしたら良いですか?

アプリケーションは、仕事に緩衝している深さを得るために、以下を少なくともする必要があります

  1. ウィンドウを作成する時には、深さバッファを要求してください
  2. 文脈が、作成された、作られた電流であった後に、プログラムの初期設定ルーチンでglEnableで(GL_DEPTH_TEST)ので、呼び出し に を置いてください
  3. zNearzFarを切り取っている飛行機が正確および適正な深さバッファ精度を提供する方法にセットされることを保証してください
  4. GL_DEPTH_BUFFER_BIT それゆえ glClearへのパラメータ 一般に、ORをbitwiseする GL_COLOR_BUFFER_BITなどの他の値によってした を通過してください

ウェブ which 使用深さ緩衝 で入手可能な多くのOpenGL例プログラムがあります。 もし仕事に正しく緩衝している深さを得るトラブルをしているならば、何が別にされるかをわかるために例プログラムを見ることから利益を得ているでしょう。 このFAQは、例OpenGLコードを持っているいくつかのウェブサイトへのリンクを含んでいます

12.020  パースペクティブ描画において、デプスバッファが働きません。どうしてですか?

呼び出しにおいて、zNearzFarを切り取っている飛行機がglFrustum()または() gluPerspectiveであることに正しく指定されることを確かめてください

多くのプログラマーが犯す誤りは、0.0のzNearを切り取っている飛行機値または許されないネガティブな値を指定することです。 zNearzFarを切り取っている飛行機は、目の前で距離を表しているポジティブな(notで、0またはネガティブ)価値です。

() gluPerspectiveなので、0.0 に のzNearを切り取っている飛行機値を指定することは、OpenGLエラーを発生させないけれども、まるでそれが使用不可にされるかのように、それは、行為に緩衝している深さを起こすかもしれません。 ネガティブなzNearまたはzFarを切り取っている飛行機価値は、不適当な結果を引き起こします。

0またはネガティブのzNearまたはzFarを切り取っている飛行機価値は、glFrustum()に手渡される時に、glGetError()を呼んで訂正できるエラーを引き起こします。 機能はその時無-opとして作動します。

12.030  デプスバッファに以前保存されたデプスイメージを書き込むにはどうしたら良いですか?

GL_DEPTH_COMPONENTに設定されたフォーマットパラメータによってglDrawPixels()コマンドを使ってください。 glColorMaskへの呼び出しによってこれをする時には、色バッファから離れてマスキングしたいかもしれません(GL_FALSE、GL_FALSE、GL_FALSE、GL_FALSE); .

12.040  デプスバッファは動いているように見えます。けれどもポリゴンが突き抜けて前に出ているところがあります。何が起こっているのでしょうか?

zNearzFarを切り取っている飛行機を、深さバッファ精度を厳しく制限する方法で設定したかもしれません。 一般に、これは、0.0と近すぎるzNearを切り取っている飛行機価値により起こされます。 zNearを切り取っている飛行機が0.0とますますより近くされると、深さバッファの効果的な精度がドラマチックに減少します。 目からzFarを切り取っている飛行機をさらに向こうに動かすことは、いつも深さバッファ精度へのネガティブなインパクトを持っているけれども、それは、zNearを切り取っている飛行機を動かすのと同じくらいドラマチックなものではありません。

glFrustum()のためのOpenGL参照マニュアル記述は、乱暴に、log2(zFar/zNear)ビットの精度が失われると言って、深さ精度を、zNearzFarを切り取っている飛行機と関係づけます。 はっきりと、zNearが0、この方程式に近づくと、無限に近づきます。

青い本記述が、関係を指摘することを得意とする間、それは多少不正確です。 比率(zFar/zNear)が増大するので、少ない精度は深さバッファの後ろの近くで入手可能で、より多くの精度は近くで深さバッファの正面に利用可能です。 従って、もしそれらがビューアからより遠いならば、プリミティブはよりZにおいて対話しそうです。

場面をするために深さバッファに十分な精度を単に持っていないことは可能です。 詳細についてはこのセクションの中で最後の問題を見てください

共面のプリミティブを引いていることは、また可能です。 一般に、共面のプリミティブのための「Z戦い」のため、ラスタ化のエラーまたは違いからラウンド離れて作成します。 共面のプリミティブをする時に、ここには、あなたを補助するいくつかのオプションがあります

12.050  デプスバッファの精度がとても低いのはなぜでしょうか?

目座標の深さバッファ精度は、zFarからzNearまでzFarを切り取っている飛行機およびオブジェクトが、zNearを切り取っている飛行機からどのくらいである比率で強く影響されます

し 何 あなた zNearを切り取っている飛行機を出し、zFar飛行機を中になるべく引く缶 でも必要があります

より具体的であるように、目座標から深さの変化を考慮してください

xeyezewe

ウィンドウ座標に

xwywzw

過ぎることに指定されたパースペクティブ投射行列によって

glFrustum(l、r、b、t、n、f);

そして、デフォルトビューポート変化を仮定してください。 zのクリップ座標c そしてwc そうです

zc =-ze* (f+n)/(f-n) - we* 2*f*n/(f-n)

wc =-ze

なぜ取り消し? OpenGLはプログラマーに提出したい 投射および投射の後の左ききの座標系の前の右ききの座標系 。

そして、ndc座標

zndc = zc /wc [-ze * (f+n)/(f-n) - we * (f-n)2*f*n/] /-ze

(f-n)(f+n)=/+(we /ze) * 2*f*n/(f-n)

深さによるビューポート変化スケールとオフセットは及び(それを、[0と1]であると仮定してください)、それから、s =(のため2の重さがありますn-1) nが深さバッファのビット深さである所:

zw = s*[(we /ze) * f*n/((f-n) +0.5*(f+n)/(f-n)+0.5] 

zを表現するために、この方程式を組み替えましょうe /we zの機能としてw

ze /we = f*n/(f-n) (zw /s) - 0.5*(f+n)/(f-n) - 0.5)

= f * n (zw /s) *(f-n) - 0.5*(f+n) - 0.5*(f-n))

= f * n (zw /s) *(f-n) - f)[*]

現在は2ポイントを見ましょう zNearを切り取っている飛行機とzFarを切り取っている飛行機 :

zw = 0 => ze /we = f * n (-f)/=-n

zw = s => ze /we = f * n /((f-n) - f) = -f

固定ポイント深さバッファ、zにおいてw 整数に量子化されます。 向こうの隣の再贈物に適したzバッファ深さは、クリップ飛行機から1とs-1です:

zw = 1 => ze /we = f * n /((1/s)*(f-n) - f)

zw = s-1 => ze /we = f * n /((/s(s-1))*(f-n) - f)

現在はいくつかの数、例えばn = 0.01に詰めましょう f = 1000とs = 65535 (すなわち、16ビット深さバッファ

zw = 1 => ze /we =-0.01000015

zw = s-1 => ze /we =-395.90054

この最後のラインについて考えてください。 目同等深さ-395.9から-1000までのすべては、マップにzバッファの65534または65535に持っています。 zNearzFarを切り取っている飛行機の間の距離のうちの約2/3は、2つのz-バッファ価値のうちの1つを持ちます!

z-バッファ解像度をさらに分析することによりそれのデリバティブは取られましょう zについての[*] w

d(ze /we) /d zw = - f * n *(f-n)*(1/s) (zw /s) *(f-n) - f)2

現在、zでそれを評価してくださいw = s

d(ze /we) /d zw = - f *(f-n)*(1/s) /n

= - f *(f/n-1) /s[**]

もしzFarを切り取っている飛行機の近くで深さバッファが有益であってほしいならば、この価値を目スペースのオブジェクトのサイズより少しに保持する必要があります(ほとんどの実用のために 世界スペース )。

12.060  zNear クリッピングプレーンをオフにするにはどうすれば良いで すか?

切り取っているセクションでこの問題を見てください

12.070  前面の方がデプスバッファの精度が高いのはなぜですか?

投射行列がクリップ座標を変換した後に、XYZ-頂点価値はそれらのクリップ同等W価値により分割されて、それは、標準化された機器座標を結果として生じます。 このステップはパースペクティブ分割として知られています。 クリップ同等W価値は目からの距離を表しています。 目からの距離として、増大する 1/Wが0に近づきます。 従って、X/WおよびY/Wは0にも近づき、されたプリミティブに少ないスクリーンスペースおよびより小さいようになりなさいを占めさせます。 これは、どのようにコンピュータが透視図法をシミュレーションするかです。

実際、それへの動作または向こうは、目から、距離の間にすでにあるオブジェクトのためのそれほど深くない効果があります。 例えば、もし顔の前でコンピュータスクリーンに6インチ近くに動くならば、それは明白なサイズです まったくドラマチックに増大するはずである 。 一方では、もしコンピュータスクリーンがあなたからすでに20フィート離れているならば、動きは、6インチ近くに、その明白なサイズへの小さな目立っているインパクトを持っているでしょう。 パースペクティブ分割によりこれは考慮されます。

パースペクティブ分割の一部として、Zはまた、同じ結果によってWにより分割されます。 すでに眺めボリュームの後ろと近いオブジェクトのために、1つの同等なユニットの距離の間の変化が、Z/Wへのオブジェクトが眺めボリュームの正面の近くにあるより少ないインパクトを持っています。 言い換えると、オブジェクト同等Zユニットは、眺めボリュームの正面と近いNDC-深さスペースの眺めボリュームの後ろの近くでそれがするより大きいスライスを占めます。

要約において、パースペクティブ分割は、その性質のため眺めボリュームの正面と近い後ろの近くより多いZ精度を起こします

このセクションの先決問題は、関連した情報を含んでいます

12.080  普通の大きさには十分な精度があるデプスバッファが、私の扱う巨大なシーンでは十分ではありません。なにかいい方法はありますか?

典型的なアプローチはマルチパステクニックを使う必要があります。 アプリケーションは、幾何学データベースを、Zでのお互いに妨げない領域に分割できます。 個々の領域がされる前に、個々の領域の幾何学は、その時、深さバッファの空所によって、最も遠い領域で始まってされます。 こちら 全体の深さバッファの精度が個々の領域に利用可能にされる 。