我對每個輸出像素都要執行一次計算,它使用從着色器管道中的早期步驟傳遞的一些數據 - 因此在片段着色器中執行此計算最有意義。爲了查看它是否可能,我從最簡單的例子開始 - 只爲每個基元計算像素。這僅需要兩個着色器 - 頂點着色器:僅對可見像素執行片段着色器
#version 430
in vec3 position;
void main() {{
gl_Position = vec4(position, 1);
}}
和片段着色器:
#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);
}}
正如你可以看到它只是增加着色器的存儲緩衝對象的元素。
然後我餵它兩個三角形(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!順便說一句,如果我將所有輸入Z座標設置爲零,那麼紅色三角形在頂部,而綠色是半隱藏的 - 在這種情況下,計數是正確的。當我閱讀OpenGL文檔(我發現選項early_fragment_tests
)時,我明白由於任何原因(例如在我的情況下深度測試)丟棄的片段不會影響原子計數器和SSBO - 請參閱here。但正如我的例子所顯示的,他們顯然影響他們!還有什麼可以解決這個問題嗎?
如果這很重要,我使用intel skylake iGPU,OpenGL 4.3在linux下運行它。
您確定深度測試正常嗎? (已啓用深度測試,沒有寫入蒙版,深度func可以...)您可以通過更改三角形的Z值並查看頂部三角形是否更改來檢查此問題。你使用哪個Z值?對兩個三角形使用完全相同的值可能會導致您的問題。你是否嘗試手動丟棄一些碎片以查看這是否改變了原子計數器? – dv1729
你以哪種順序繪製三角形?當您繪製紅色然後綠色時,結果並不令人驚訝,因爲紅色三角形在渲染時完全可見。 – BDL
我提到我用兩個三角形(6點)提供着色器 - 我只需一次調用DrawArrays即可完成此操作。 – aplavin