一致するサーフェスとのZファイティングの回避


26

2つのオーバーラップする同一平面サーフェスをレンダリングする場合、一般的な問題は「zファイティング」です。レンダラーは2つのサーフェスのどちらがカメラに近いかを判断できず、オーバーラップ領域に視覚的なアーチファクトを与えます。

これに対する標準的な解決策は、モデルの設計時に表面にわずかなオフセットを与えることです。他の解決策はありますか?


2
対数深度バッファをチェックアウトできます。上の記事がありますgamasutra
ソーピー

1
「共面」と言うとき、「ほぼ」または「正確に」共面を意味しますか。後者の場合、それらの表面は同一の表面/三角形ですか。レンダリングハードウェアは、最後のケースでは決定的であり(ランダムな順序で送信していないと仮定)、戦闘はありません。同一ではないが正確に同一平面上のサーフェスの場合、モデルを更新して、サーフェスを重複部分と非重複部分に分割できますか?
サイモンF

@SimonF、「共面」とは、「まったく共面」を意味します。Soapyのソリューションは、「ほぼ同一平面上」の場合にのみ機能します。
マーク

表面の例を挙げていただけますか?@SimonFが述べたように、私が頭の外から考えることができる唯一のことは、三角形の複製です。
-RichieSams

@RichieSams私が考えることができる最も一般的なケースは、デカールです。ここでは、三角形を正確に複製する必要はありません。
rys

回答:


10

表面が完全に同一平面上にある場合、あなたの運命はFPUの神次第です。Zファイティングが発生する可能性が高くなります。三角形がある場合は、同一とあなたが正確にそれぞれに同じ数学を、あなたがしますどちらも同じZ値で終わります。しかし、繰り返しますが、これは数学演算が両方で同じ場合にのみ起こります。(一般に、FPU操作は可換ではないため)

考えられる解決策の1つは、Zバッファーをまったく使用しないことです。代わりに、Painter's Algorithmを使用できます。確かに、これにはペインターアルゴリズムのすべての問題が伴います。しかし、それはZファイティングを解決するでしょう。

スクリーンスペースデカール(SSD)の例では、一般的な解決策は、単純な薄い立方体であるオフセットを使用することです。参照用に、SSDに関するWarhammer 40kのプレゼンテーションを参照してください。またはBart Wronskiの投稿では、デカールに関する他のいくつかの問題に対処していますが、SSDに関する他のいくつかのプレゼンテーションへのリンクもあります。


5
同じトランスフォームで同じジオメトリを再レンダリングすると、毎回同じ深度値が確実に生成されます。(つまり、ではありません意志です)。たとえば、マルチパス前方照明が機能するのはこのためです。
ネイサンリード

@NathanReed修正済み。説明をありがとう
-RichieSams

1
:あなたはGLSLで不変修飾子を使用する必要があり、その機能を取得するにはopengl.org/wiki/Type_Qualifier_%28GLSL%29#Invariance_qualifiers
ashleysmithgpu

一部の最適化はシェーダーの残りの部分に依存する可能性があるため、頂点位置を評価する際の同一のシェーダー式(および入力)は、同一の結果を得るのに十分ではない場合があることに注意してください。GLSLには、異なるシェーダーで同じように評価する必要があるシェーダー出力を宣言するための「不変」キーワードがあります。
-Firadeoclus

2

過去にこれを解決した方法は次のとおりです。

  1. 深度テストではなく、深度書き込みにより、最初のオブジェクト(他のオブジェクトの背後に表示されるオブジェクト)を描画します
  2. 深度テストと深度書き込みにより2番目のオブジェクトを描画します。手順1で深さを記述しなかったため、これによりZファイティングが発生することはありません。
  3. カラーバッファではなく、深度バッファに書き込むだけで最初のオブジェクトを描画します。これにより、オブジェクト2ではなく、オブジェクト1で覆われているピクセルの深度バッファーが最新の状態になります。

これを機能させるには、オブジェクトを連続して描画する必要があることに注意してください。


0

レンダラーによっては、アルゴリズムのようなノイズを使用して、マルチサンプリング深度で極小オフセットを適用することで、サーフェスをより「ファジー」にすることができます。これにより、深度が近接しているサーフェスに対して一種のブレンド効果が得られるはずです。私が知っているのは、フラグメントシェーダーでサンプルごとの深さを設定することは、OpenGLではごく最近であり、拡張機能としてのみです。

OpenGLにはPolygonOffsetがありますが、同一平面上にあるものをレンダリングしようとしていることを事前に知る必要があります。単一のモデル内のサーフェスには適していませんが、たとえば、一部の土地にオーバーレイされた道路をレンダリングする場合、うまく機能します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.