GPUが位置のためにクリップスペースZをWで分割するのはなぜですか?


8

背景:
正規の頂点変換を少し変更するだけで、線形深度バッファーを使用するのが非常に簡単であることがわかりました。最も簡単な方法は、https://www.mvps.org/directx/articles/linear_z/linearz.htmの下部にあります

ただし、注意すべき点は、ニアプレーンまたはファープレーンに対してクリップする必要のない三角形に対してのみ機能することです。(そして、頂点シェーダーでパースペクティブ分割を実行する別の解決策は、他の4つの錐台平面に対して同様の問題を引き起こします。)

クリッピングは4つのクリップ空間座標すべてで機能するために線形補間を必要とするため、頂点シェーダーのみを使用して線形深度を処理することは不可能だと思います。しかし、その理由はすべてZがWで除算されることにあります。

なぜそれが行われるのですか?XとYはカメラからの距離で分割する必要がありますが、Z座標はNDCボックスに完全にフィットするために分割されません。

回答:


13

パースイメージを実行していて、モデルに暗黙の交差がある場合、「線形Z」を使用すると、それらの交差が間違った場所に表示されます。

たとえば、電柱の列があり、遠くに後退し、地面を突き抜けている(そして下に続く)単純な地面を考えてみましょう。暗黙的な交差は、補間された深度値によって決定されます。それらがで補間されていない1/Z場合、投影された頂点が遠近法で計算されていると、画像は正しく表示されません。

以下のイラストの非美的品質をお詫び申し上げますが、私はそれらを'97年に戻しました。

最初の画像は、必要なレンダリング効果を示しています。(青い「パイロン」は地面の下にかなり長い距離を移動するため、画像の下部で切り取られていることに注意してください)

ここに画像の説明を入力してください

この2番目の画像は、非相互深度バッファーを使用した結果を示しています。

ここに画像の説明を入力してください

ご覧のとおり、結果は正しくありません。

別のメモでは、本当にあなた線形のZ表現を本当に望んでいるのですか?遠近法でレンダリングしている場合、確かに遠方よりもカメラに近い方の精度が必要ですか?

後のコメントについて:

「それらが1 / Zで補間されていない場合」私には理解できません。それは何の補間ですか?

最初に注意する点は、標準の透視投影では、ワールド空間の直線は透視空間の直線のままであることです。ただし、距離/長さは保持されません。

簡単にするために、簡単な透視変換を使用して頂点を投影すると仮定します。

XScreen=XWorldZWorld
YScreen=YWorldZWorld
我々はすべきも相互のスクリーン空間の深さを計算し、例えば
ZScreen=1ZWorld
しかし、深度バッファの線形Zには、次のようなものが必要です。
ZScreen=scaleZWorld
(ここでは、scale = 1と想定できます)

ワールドスペースの終点を持つラインがあるとしましょう

[001]and[200010]
これらのマップをスクリーンスペース座標にマッピングするパースペクティブ
[001]and[2000.1]

レンダリングシステム/ハードウェアは、画面スペースzを線形補間するため、ラインの1/2ウェイポイントで、画面上に表示されるため、つまりピクセル(10、0)で、投影された(逆)Zを取得します。値は0.55です。これは、ワールドスペースのZ値が〜1.818に相当します。開始Z値と終了Z値を指定すると、これは線の長さに沿って約20%です。

代わりに、元のZ値を使用して補間しようとした場合、Zはワールドスペース値5.5に対応することになります。何も交差しない限り、あなたは大丈夫かもしれませんが(私はそれについて徹底的に考えていませんでした)、暗黙の交差持つものすべて正しくありません。

私が言及しなかったことは、パースペクティブ補正テクスチャリング(またはパースペクティブ補正シェーディングさえ)を導入したら、1 / wのピクセルごとの補間を実行し、さらに、その補間された値の逆数をピクセルごとに計算する必要があることです。


数学や図表がなければ、この答えを理解することはできないと思います。そして、はい、より正確で、近いほど、おそらく理にかなっていますが、far / z標準的な線形によるからのスケーリングは意味がありません。これにより、2つのクリップ面が互いに近づくほど線形になる深度バッファが生成されます。これは、画面空間リニアZとパフォーマンスハックのための非一定の深度バッファマッピングという2つの概念の融合のようです。
Jessy

具体的には、「1 / Zで補間されていない場合」のことです。それは何の補間ですか?
ジェシー2018

1
うまくいけば説明するためにいくつかのテキストを追加します
Simon F

ありがとう!問題は「レンダリングシステム/ハードウェアが画面空間zを線形補間する」にあると思います。NDCの位置は(x, y, z) / wフラグメントごとに計算されるという印象を受けましたが、代わりに、線形補間されたバージョンの(x/w, y/w, z/w)?を処理する必要があります。それは2018年には私には理にかなっているように見えますが、それが今のところ一緒に生きなければならないハックであるかどうかを知るのは良いことです!
Jessy

パースペクティブ補正テクスチャリング/シェーディング/その他を実行するには、(Val / w)値を線形補間し、フラグメントごとに、線形補間された1 / wで除算する必要があります。コメントだけで説明するのは少し難しいですが、computergraphics.stackexchange.com / a / 4799/209に少し説明があります。または、ジムブリンの記事「Hyperbolic Interpolation」を検索します
Simon F

6

デプスバッファにZ / Wを使用すると、ニアプレーンとファープレーンに対するクリッピングよりもさらに深くなります。サイモンが言及したように、これは、ラスタライズ中の三角形の頂点間の補間に関係しています。

Z / Wは、画面空間で頂点からNDC深度値を単純に線形補間することにより、三角形の内部のポイントに対してNDC深度値を正しく計算できるようにする独自のオプションです。原則として、カメラ空間Zを深度バッファ値にマップするために好きな関数を使用できますが、Z / W以外の選択では、ピクセルごとに複雑な計算を行う必要があり、速度が遅くなり、計算が難しくなります。ハードウェアで構築します。

線形深度バッファを使用する場合、もちろん、線形補間の深度値はワールドスペースでは正しくなりますが、一般的にはスクリーンスペースでは正しくありません。また、ラスタライズで重要なのは画面スペースです。スクリーンスペースの境界内で、各ピクセルセンターまたは他のサンプルポイントの遠近法に正確な深度値(およびUVのような他の属性値)を生成できる必要があるためです。ラスタライズされる三角形。


GPUの設計方法はわかりませんが、必要なことは、線形深度の場合はZ / WではなくZを補間することだけであり、表示されているものについてはその後もZ / W補間が発生する可能性があるようです。これが正当な理由の問題なのか、「誰も気にしないので更新の手間をかけない」の問題なのか、私にはまだわかりません。
ジェシー2018

Z / Wの代わりにZを補間すると、画面スペースで正しい結果得られません。Z / Wはそうします。
ネイサンリード、

正しい。しかし、深度バッファーが位置よりも低い精度で量子化されている場合、機能するときのパフォーマンスは別として、スクリーンスペースZのスケーリングされたチャンクを保存することはお勧めできません。ビュースペースで発生します。そしてZは、Wによる除算の前、深度バッファー、そしてその後に行ったもののために補間される必要があります。それで私の質問への回答は、「GPUは常に最初のGPUでの唯一の実用的な解決策であり、それ以来十分にうまくいったので、GPUは常にクリップスペースでのみ補間されているため」?
ジェシー2018

「位置よりも低い精度で量子化」、または「スクリーンスペースZのスケーリングされたチャンクを格納する」についてあなたが言っていることに従っていません。
Nathan Reed、

1
また、「深度バッファの場合、Wで除算する前にZを補間する必要があります」-いいえ。それが私が説明しようとしてきたことです。最初にWで除算せずに画面スペースでZ(または他の何か)を補間すると、間違った答えが得られます。Wで除算しない場合、線形Zバッファーは機能するというこの考えに行き詰まっているようです。しかし、機能しません。画面スペースで適切に補間されません。
Nathan Reed、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.