我使用計算着色器將單像素點渲染到uint32紋理中。紋理是3d紋理,x和y是視口座標,z具有座標0和1上的附加屬性的深度信息,因此如果您願意,可以使用兩個手動構建的rendertargets。代碼看起來像這樣:手動深度渲染:儘管使用原子操作的隨機結果
layout (r32ui, binding = 0) coherent volatile uniform uimage3D renderBuffer;
layout (rgba32f, binding = 1) restrict readonly uniform imageBuffer pointBuffer;
for(int j = 0; j < numPoints/gl_WorkGroupSize.x + 1; j++)
{
vec4 point = imageLoad(pointBuffer, ...)
// ... transform point ...
uint originalDepth = imageAtomicMin(renderBuffer, ivec3(imageCoords, 0), point.depth);
if (originalDepth >= point.depth)
{
// write happened, store the attributes
imageStore(renderBuffer, ivec3(imageCoords, 1), point.attributes);
}
}
雖然深度值是正確的,我有幾個像素在兩個值之間閃爍的屬性。
pointBuffer中點的順序是隨機的(但我已經驗證了所有點的集合總是相同的),所以我的第一個想法是兩個相等的深度值可能會更改輸出,具體取決於哪一個來自第一。所以我做了它,if originalDepth == point.depth
它使用imageAtomicMax
始終具有相同的兩個替代屬性書面,但沒有改變。
我散落在各地barrier()
和memoryBarrier()
,但這並沒有改變。我也爲此刪除了所有分歧的控制流,沒有任何改變。
將本地工作大小減少到32個可消除90%的閃爍,但仍有一部分依然存在。
任何想法將不勝感激。
編輯:之前你問我爲什麼手動做這個東西,而不是使用正常的光柵化和片段着色器,原因是性能。光柵化器沒有幫助,因爲我渲染單像素點,共享內存大大加快了速度,並且我多次渲染每個點,這就要求我使用速度較慢的幾何着色器。
我自己寫了一封評論,直接在imageStore上面聲明「這裏有潛在的競爭條件」,但由於某種原因決定不承擔責任。可能太專注了......反正謝謝:)我正在渲染一個64x64 shadowmaps的地圖集,並且每個SM都有一個工作組,但這太大了,無法在共享內存中使用深度緩衝區。兩個問題:每個工作組列表不只是將問題從全局移動到共享內存,我還需要解決那裏的競爭條件?其次,流水線會需要幾個調度調用嗎? – karyon
「*每個工作組列表不只是將問題從全局移動到共享內存,我還需要解決那裏的競爭條件?*」是的,但有些事情可以在那裏解決,這些都相對便宜。 –
一個指針從哪裏開始將是很好的,因爲我在這裏結束了我的知識,這東西很難谷歌...... – karyon