出力の各ピクセルに対して計算が行われ、シェーダパイプラインの以前のステップから渡されたデータが使用されます。この計算をフラグメントシェーダで実行するのが最も理にかかります。私が最も簡単な例で始めたかどうかは、各プリミティブのピクセル数をカウントするだけです。あなたはそれだけで、シェーダ記憶バッファオブジェクトの要素をインクリメント見ることができるように可視ピクセル専用のフラグメントシェーダを実行
#version 430
layout(early_fragment_tests) in;
out vec4 out_color;
layout(std430, binding = 3) buffer out_data {
int data[];
};
void main() {{
atomicAdd(data[gl_PrimitiveID], 1);
out_color = vec4(1, gl_PrimitiveID, 0, 1);
}}
:
#version 430
in vec3 position;
void main() {{
gl_Position = vec4(position, 1);
}}
とフラグメントシェーダ:頂点シェーダ - これは2つだけのシェーダが必要です。
次に、2つの三角形(6点)を入力します:[-1, -1, 0], [-1, 1, 0], [1, 1, 0], [-1, -1, 0], [1, -1, 0], [-1, 1, -1]
。赤い三角形と緑色の三角形が正しく表示されますが、それぞれがウィンドウの半分を占めていますが、緑の三角形が上にあるため、赤い三角形の半分(ウィンドウの1/4)しか表示されません。
もちろん、赤い三角形の場合はウィンドウサイズの1/4、緑色の場合は約1/2になると予想されましたが、それらは両方とも1/2に等しいです! Btw、すべての入力Z座標をゼロに設定すると、赤い三角形が一番上にあり、緑色が半分隠されています。この場合、カウントは正しいです。
OpenGLドキュメント(私がオプションearly_fragment_tests
を見つけたところ)を読んでいるうちに、何らかの理由で破棄された断片(例えば、私の場合のように深度テスト)がアトミックカウンタとSSBOに影響しないことを理解しました - hereを参照してください。しかし私の例が示すように、彼らは明らかにそれらに影響を与えます!問題を解決できるものは他にありますか?
これが重要なのであれば、Intel Skylake iGPU、OpenGL 4.3を使ってLinux上で実行しました。
深度テストが正常に機能していますか? (深度テストを有効にし、書き込みマスクなし、深度関数は正常です...)これは、三角形のZ値を変更し、上三角形が変化するかどうかを調べることで確認できます。どのZ値を使用していますか?両方の三角形にまったく同じ値を使用すると、問題が発生する可能性があります。これが原子カウンタを変更するかどうかを確認するためにフラグメントを手動で破棄しようとしましたか? – dv1729
どのような順序で三角形を描いていますか?赤とそれに続いて緑を描画すると、レンダリングされた時点で赤い三角形が完全に表示されるため、結果は驚くことではありません。 – BDL
私は、2つの三角形(6点)でシェーダーにフィードすると言いました - そして、私はDrawArraysを一回呼び出すだけでこれを行います。 – aplavin