
Zバッファ(深度バッファとも呼ばれる)は、コンピュータグラフィックスにおいてフラグメントの深度情報を格納するために使用されるデータバッファの一種です。格納される値はカメラまでの距離を表し、0が最も近い値となります。エンコーディング方式は反転させることができ、数値が大きいほどカメラに最も近い値となります。
3Dレンダリングパイプラインでは、オブジェクトがスクリーンに投影される際に、投影されたスクリーン画像内の生成されたフラグメントの深度(z値)が、バッファに既に格納されている値(深度テスト)と比較され、新しい値の方が近い場合は置き換えられます。これは、カラー値を計算するラスタライザーと連携して動作します。ラスタライザーによって出力されたフラグメントは、他のフラグメントと重ならない限り保存されます。
Zバッファリングは、現代のほとんどすべてのコンピュータ、ノートパソコン、携帯電話で3Dコンピュータグラフィックスを生成するために使用されている技術です。現在、主な用途は、3Dシーンの高速かつ正確な処理を必要とするビデオゲームです。
画面に表示すべき内容と表示すべき内容を決定するには、さまざまな手法を用いる多段階のプロセスが必要です。Zバッファの使用は、このプロセスの最終段階となります。
オブジェクトがフレームバッファにレンダリングされるたびに、zバッファを使用してフラグメントのz値をzバッファに既に格納されているz値と比較します(つまり、どちらが近いかを確認します)。新しいz値が古い値よりも近い場合、フラグメントはフレームバッファに書き込まれ、この新しい近い値がzバッファに書き込まれます。z値がzバッファの値よりも遠い場合、フラグメントは破棄されます。これはシーン内のすべてのオブジェクトとサーフェスに対して繰り返されます(多くの場合、並列に実行されます)。最終的に、zバッファによって通常の奥行き知覚が正しく再現されます。つまり、近いオブジェクトは遠いオブジェクトを隠します。これをzカリングと呼びます。
Zバッファの粒度はシーンの品質に大きな影響を与えます。従来の16ビットZバッファでは、2つのオブジェクトが非常に近い場合、アーティファクト(「Zファイティング」または「スティッチング」と呼ばれる)が発生する可能性があります。より新しい24ビットまたは32ビットZバッファははるかに優れた動作を示しますが、追加のアルゴリズムなしではこの問題を完全に解消することはできません。8ビットZバッファは精度が低すぎるため、ほとんど使用されません。
光源の視点からサーフェスをレンダリングして得られたZバッファデータにより、シャドウマッピング技術によって影を作成することができる。[ 1 ]
Zバッファリングは、1974年にヴォルフガング・シュトラッサーが、遮蔽されたオブジェクトをレンダリングするための高速アルゴリズムに関する博士論文で初めて記述しました。[ 2 ]重なり合うポリゴンを決定する同様の解決策は、ペインターズアルゴリズムです。これは、効率と不正確な結果を犠牲にして、不透明なシーン要素を処理できます。
Zバッファは、一般消費者向けグラフィックカードのハードウェアに実装されることが多い。また、Zバッファリングは、映画におけるコンピュータ生成特殊効果の制作にも(ハードウェアではなくソフトウェアとして)利用される。
粒度が十分に小さくても、 zバッファの距離値の精度が距離全体に均等に分布していないと、画質の問題が発生する場合があります。近い方の値は遠い方の値よりもはるかに精度が高く(そのため、近い方のオブジェクトをより良く表示できます)、一般的にはこれは望ましいことですが、オブジェクトが遠くなるにつれてアーティファクトが発生する場合があります。精度をより均等に分布させるzバッファリングのバリエーションはwバッファリングと呼ばれます(下記参照)。
新しいシーンの開始時には、zバッファを定義済みの値(通常は1.0)にクリアする必要があります。これは、この値が深度の上限(0から1のスケール)であり、ビューフラスタムを通してこの時点ではオブジェクトが存在しないことを意味します。
zバッファの概念の発明は、多くの場合エドウィン・キャットマルに帰せられるが、ヴォルフガング・シュトラッサーはキャットマルの発明の数ヶ月前の1974年の博士論文でこのアイデアについて述べていた。[ a ]
1999年から2005年までの比較的新しいPCグラフィックカードでは、zバッファ管理に利用可能なメモリ帯域幅のかなりの部分が使用されます。zバッファリングのパフォーマンスコストを削減するために、ロスレス圧縮(圧縮/解凍に必要なコンピュータリソースは帯域幅よりも安価)や、超高速ハードウェアzクリアなど、さまざまな方法が採用されています。ハードウェアzクリアは、「1フレームを正、1フレームを負」という手法(符号付き数値を使用して深度を巧みにチェックし、フレーム間のクリアを完全にスキップする)を不要にします。
特にNintendo 64のライフサイクルの後半に発売されたいくつかのゲームでは、メモリ帯域幅とメモリ要件をそれぞれ削減するために、zバッファリングを最小限に抑える(例えば、zバッファリングなしで最初に背景をレンダリングし、前景オブジェクトにのみzバッファリングを使用する)か、完全に省略することにした。Super Smash Bros.とF-Zero Xは、フレームレートを上げるためにzバッファリングを最小限に抑えた2つのNintendo 64ゲームである。Factor 5のいくつかのゲームもzバッファリングを最小限に抑えたり省略したりした。Nintendo 64では、zバッファリングを使用すると、zバッファリングを使用しない場合と比較して最大4倍の帯域幅を消費する可能性がある。[ 3 ]
PC版Mechwarrior 2は、zバッファリングを使用していなかったため、オリジナルの4MB 3dfx Voodooで最大800 × 600の解像度をサポートしていました[ 4 ] 。
レンダリングにおいて、Zカリングとは深度に基づいてピクセルを早期に除去する手法であり、隠れた面のレンダリングにコストがかかる場合にパフォーマンスを向上させる効果があります。これはZバッファリングの直接的な結果であり、各ピクセル候補の深度を、そのピクセルが隠れている可能性のある既存のジオメトリの深度と比較します。
Zバッファを使用する場合、ピクセルの深度が判明した時点でそのピクセルをカリング(破棄)できるため、そもそも表示されないピクセルのライティングやテクスチャリングといった処理全体をスキップできます。また、時間のかかるピクセルシェーダーは、カリングされたピクセルに対しては一般的に実行されません。そのため、フィルレート、ライティング、テクスチャリング、またはピクセルシェーダーが主なボトルネックとなっている状況では、Zカリングは優れた最適化手法となります。
Zバッファリングではジオメトリをソートせずに使用できますが、ポリゴンを深度順にソートする(つまり、リバースペインターのアルゴリズムを使用する)ことで、各画面ピクセルのレンダリング回数を減らすことができます。これにより、オーバードローが多いフィルレート制限のあるシーンでのパフォーマンスを向上させることができますが、Zバッファリングと組み合わせない場合は、次のような深刻な問題が発生します。
そのため、リバースペインターのアルゴリズムは、zカリングの最適化として以外は、(大掛かりな再設計なしには)zカリングの代替として使用することはできません。例えば、2つのポリゴンが遮蔽相互作用を起こす可能性があるかどうかを迅速に判断するために、ポリゴンをx/y座標とz深度に基づいてソートして境界を提供するという最適化が考えられます。
レンダリングされるカメラ空間の深度値の範囲は、多くの場合、そして値。
視点変換後、新しい価値は、 またはは次のように定義されます。
正射影後、新しい値は、 またはは次のように定義されます。
どこ古い値はカメラ空間では、時にはまたは。
結果として得られる値は-1 から 1 の値の間で正規化され、飛行機は-1にあり、平面は1の位置にあります。この範囲外の値は、視錐台内にない点に対応しており、レンダリングされるべきではありません。
通常、これらの値はハードウェアグラフィックスアクセラレータのZバッファに固定小数点形式で格納されます。まず、適切な変換を行うことで、より一般的な範囲である[0, 1]に正規化されます。前の式に代入します。
簡略化:
第二に、上記の式にここで、d は z バッファの深さ (通常は 16、24、または 32 ビット) であり、結果を整数に丸めます。[ 5 ]
この式を逆算して導出することで、zバッファ解像度(前述の「粒度」)を計算できます。上記の式の逆数:
どこ
カメラ空間におけるzバッファの解像度は、zバッファに格納されている整数の最小変化(+1または-1)から得られる増分値になります。したがって、この解像度は、の導関数から計算できます。関数として:
カメラ空間の用語で表現し直すと、上記により:
これは、近くには、平面上では、遠くでははるかにまばらになり、結果としてカメラに近いほど精度が向上します。つまり、精度が低いほど遠くにある平面が近すぎると、遠くのオブジェクトに望ましくないレンダリングアーティファクトが発生する一般的な原因となります。[ 6 ]
zバッファを実装するには、は現在のポリゴンの頂点間のスクリーン空間全体にわたって線形補間され、これらの中間値は通常、固定小数点形式でzバッファに格納されます。
wバッファを実装するには、[ 7 ]古い値カメラ空間では、またはは、一般的に浮動小数点形式でバッファに格納されます。ただし、これらの値は頂点からスクリーン空間全体に線形補間することはできません。通常は、反転、補間、そして再度反転する必要があります。結果として得られる値は、対照的には均等に間隔を空けて配置されていますそしてwバッファの実装の中には、反転を完全に回避するものもあります。
ZバッファとWバッファのどちらがより良い画像をもたらすかは、アプリケーションによって異なります。
以下の擬似コードは、Zバッファリングのプロセスを示しています。
// まず、各ピクセルの深度を初期化します。 d(i, j) = 無限大 // 最大長 // 各ピクセルの色値を背景色で初期化します c(i, j) = 背景色 // 各ポリゴンに対して、以下の手順を実行します。 (ポリゴンの投影における各ピクセルについて) { // ポリゴンの深さ、つまりz座標を求めます // ピクセル (i, j) に対応する (x, y) の位置 (z < d(i, j))の場合 { d(i, j) = z; c(i, j) = color; } } {{cite book}}: CS1メンテナンス: 場所の発行元が見つかりません (リンク)