8

私は単純なボクセル エンジン (Minecraft を考えてください) を作成しており、現在、遮蔽された顔を取り除いて貴重な fps を得る段階にあります。私は OpenGL であまり経験がなく、glColorMask マジックがどのように機能するかをよく理解していません。

これは私が持っているものです:

// new and shiny
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// this one goes without saying
glEnable(GL_DEPTH_TEST);

// I want to see my code working, so fill the mask
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

// fill the z-buffer, or whatever
glDepthFunc(GL_LESS);
glColorMask(0,0,0,0);
glDepthMask(GL_TRUE);

// do a first draw pass
world_display();

// now only show lines, so I can see the occluded lines do not display
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

// I guess the error is somewhere here
glDepthFunc(GL_LEQUAL);
glColorMask(1,1,1,1);
glDepthMask(GL_FALSE);

// do a second draw pass for the real rendering
world_display();

これはある程度機能しますが、カメラの位置を変更すると、世界が消え始め、線が少なくなり、まったく見えなくなります。

4

3 に答える 3

10

深度バッファをクリアしていないようです。

glDepthMask(GL_TRUE);で深度バッファをクリアしようとしている間は、( を介して) 深度書き込みを有効にする必要がありますglClear。おそらく、前のフレームからまだ無効になっているため、後続のフレームですべてのクリアがノーオペレーションになります。glDepthMaskの前にコールを移動するだけglClearです。

于 2010-12-26T13:02:28.323 に答える
8

glColorMaskとglDepthMaskは、フレームバッファのどの部分に実際に書き込まれるかを決定します。

初期のZカリングの考え方は、最初にデプスバッファ部分のみを最初にレンダリングすることです。実際の節約は、ジオメトリを近くから遠くまで並べ替えることで得られるため、GPUは遮蔽されたフラグメントをすばやく破棄できます。ただし、Zバッファを描画している間は、カラーコンポーネントを描画したくありません。これにより、シェーダーの切り替え、テクスチャリング、つまり、計算量の多いすべてのものを切り替えることができます。

警告の言葉:初期のZは不透明なジオメトリでのみ機能します。実際、深度バッファアルゴリズム全体は、不透明なものに対してのみ機能します。ブレンディングを実行するとすぐに、近くまでソートする必要があり、深度バッファリングを使用しないでください(関連する問題を克服するためのアルゴリズムについては、「順序に依存しない透明度」を検索してください)。

Sブレンドされているものがある場合は、「初期Z」ステージから削除します。

最初のパスで設定します

glDepthMask(1); // enable depth buffer writes
glColorMask(0,0,0); // disable color buffer writes
glDepthFunc(GL_LESS); // use normal depth oder testing
glEnable(GL_DEPTH_TEST); // and we want to perform depth tests

Zパスが完了したら、設定を少し変更します

glDepthMask(0); // don't write to the depth buffer
glColorMask(1,1,1); // now set the color component

glDepthFunc(GL_EQUAL); // only draw if the depth of the incoming fragment
                       // matches the depth already in the depth buffer

GL_LEQUALもその役割を果たしますが、デプスバッファ内のフラグメントよりもさらに近いフラグメントを通過させることもできます。ただし、深度バッファの更新は行われないため、原点と保存された深度の間の何かが、そこに何かが描画されるたびに上書きされます。

テーマのわずかな変更は、「初期Z」が設定された深度バッファーを、その後の複数の遅延シェーディングパスのジオメトリバッファーとして使用することです。

さらにジオメトリを保存するには、オクルージョンクエリを調べてください。オクルージョンクエリでは、フラグメントがすべてのテストに合格した場合、GPUにいくつ尋ねます。これは、おそらくoctreeまたはKdツリーを使用しているボクセルエンジンです。ブランチをトラバースする前に、ツリーのブランチの空間分割面(glDepthMask(0)、glColorMask(0,0,0)を使用)を描画すると、そのブランチにジオメトリが表示されているかどうかがわかります。これを、ほぼソートされたトラバーサルとツリー上の(粗い)フラスタムクリッピングと組み合わせると、パフォーマンスが大幅に向上します。

于 2010-12-26T11:37:51.740 に答える
5

z-pre passは、半透明のオブジェクトで機能します。半透明の場合は、プリパスでレンダリングせず、zsortしてレンダリングします。

于 2011-06-21T22:03:32.633 に答える