3

ある角度から見ると、私の低木は次のように見えます。

他方から見ると、次のようになります。

私の理論では、低木を最初の角度から見たときに、低木の背後にあるすべてのブロックがすでに描画されているため、低木を描画するときは、それらを上に描画するだけです。

ただし、別の角度から見ると、基本的には最初に低木を描画しようとしており、次に低木の背後にあるブロックを描画しようとすると、深度バッファーをチェックし、ブロックのビューを既にブロックしている何かがあることを確認します。レンダリングしないと、ネイビーブルーの四角が表示されます(私のクリアカラー)。

ただし、この問題を修正する方法は本当にわかりません。深度テストを無効にすると、他のあらゆる種類のエラーが発生します。頂点またはポリゴンに透明性があることを示すフラグを立てて、背後にあるものをレンダリングする必要があることを認識させる方法はありますか?


これを見つけました。これが唯一の解決策ですか?透明なブロックと不透明なブロックを分離し、プレイヤーが動き回ることができるように、ほぼすべてのフレームでそれらを CPU で手動で並べ替えるには? これを GPU に委任する方法が必要です...

4

3 に答える 3

9

そのリンク (および CPU での並べ替え) は、アルファ ブレンディング用です。アルファ テスト (ブレンディングではない) のみが必要な場合は、何も並べ替える必要はありません。深度テストを有効にしたまま、アルファ テストを有効にするだけで、すべてが正常にレンダリングされます。

ここを参照してください: http://www.opengl.org/wiki/Transparency_Sorting ソートが必要な「標準半透明」ではなく、アルファ テストが必要な「アルファ テスト」が必要です。

于 2012-02-19T21:32:35.033 に答える
3

解決策#1:

  1. デプスバッファを有効にして、すべての不透明なオブジェクトを任意の順序で最初にレンダリングします。これには、アルファブレンディングなしでアルファテストを使用するすべてのオブジェクトが含まれます。
  2. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)オブジェクト(煙/ガラス/草)の場合:デプスバッファ書き込みを無効にして、最も遠いポリゴンから最も近いポリゴンに透明なシーンをレンダリングします(glDepthMask(GL_FALSE)。すべての透明なオブジェクトが凸状で交差していない場合は、ポリゴンの代わりにオブジェクトを並べ替えることができます。
  3. glBlendFunc(GL_SRC_ALPHA, GL_ONE)および(火、glBlend(GL_ONE, GL_ONE)「魔法の」パーティクルシステム、グロー):深度バッファ書き込み(glDepthMask(GL_FALSE))を無効にして、透明なシーンを任意の順序でレンダリングします。
  4. 手順3の後で、深度バッファが有効なオブジェクトをレンダリングしないでください。

解決策#2:
デプスピーリングを使用します(グーグルで検索します)。特に透明なオブジェクトが互いに交差する場合。ソリューション#1を必要とするパーティクルシステムや草には適していません。


次に、ほぼすべてのフレームでCPU上で手動で並べ替えます

挿入ソートは、すでにソートされているデータまたは部分的にソートされているデータに最適です。

これをGPUに委任する方法が必要です...

草のある領域とない領域をマークするチャネル(たとえば、アルファ)を​​持つテクスチャを使用して、ジオメトリシェーダーで草のポリゴンを(正しい順序で)生成できると思います。OpenGL 4が必要です。おそらく、草のパッチを生成するためにシェーダーにフィードするポリゴンに対して、ある種の高レベルの並べ替えを実行する必要があります。

個々の低木は、すべての方向で完全に対称である場合、頂点シェーダーで(+-90/180/270度)回転して、正しいポリゴンの順序を維持できます。

また、GDGPUアプローチまたはOpenCL / CUDAのいずれかを使用して、GPUで適切に並列化され、実行できるマージソートアルゴリズムがあります。

ただし、そのようなものを使用して5つの草の低木をレンダリングすることは、グレネードランチャーでゴキブリを殺そうとすることとほぼ同じです。楽しいことですが、正確には効率的ではありません。

実際にパフォーマンスの問題が発生するまで、「GPUへのオフロード」を忘れることをお勧めします。プロファイラーを使用し、最適化する前に常に測定してください。そうしないと、不要な最適化を行うために大量の開発時間を浪費することになります。

于 2012-02-19T21:58:18.450 に答える
3

WebGL または OpenGL ES 2.0 (iPhone/Android) を使用している場合、アルファ テストはありません。代わりに、透明なピクセルを描画する必要はありません。そうすれば、ピクセルが書き込まれないため、深度バッファに影響を与えません。そのためには、フラグメント シェーダーで透明なピクセルを破棄する必要があります。あなたはそれをハードコーディングすることができます

...
void main() {
   vec4 color = texture2D(u_someSampler, v_someUVs);
   if (color.a == 0.0) {
     discard;
   }
   gl_FragColor = color;
}

または、アルファ値を設定できる古いスタイルのアルファテストをシミュレートできます

...
uniform float u_alphaTest;
void main() {
   vec4 color = texture2D(u_someSampler, v_someUVs);
   if (color.a < u_alphaTest) {
     discard;
   }
   gl_FragColor = color;
}
于 2013-12-22T19:07:23.907 に答える