2013-03-27 59 views
1

作爲實驗,我決定嘗試僅使用圖像API渲染紋理。起初結果顯然是錯誤的,因爲紋理寫入發生在深度測試之前。所以我啓用了early_fragment_tests,雖然我已經介紹了這種類型的用例,但現在我得到了一種奇怪的閃爍效果,看起來像Z-fighting,這似乎很奇怪,因爲它應該執行相同的深度測試定期渲染。使用圖像API渲染到紋理(無Framebuffer)

無論如何,我已經包含了一個問題的形象,我很好奇,如果任何人有解釋發生了什麼,以及爲什麼這不起作用。它可以工作嗎?

Flickering Dwarf

這裏有一個最小的再生

#version 420 
    in vec3 normal; 
    layout(binding = 0) writeonly uniform image2D outputTex; 
    void main() 
    { 
     vec4 fragColor = vec4(normal, 1); 
     imageStore(outputTex, ivec2(gl_FragCoord.xy), fragColor); 
    } 
+0

你在說什麼「圖像API」?另外,添加一些代碼會有所幫助。 – 2013-03-28 00:29:03

+0

'ARB_shader_image_load_store' – ragnar 2013-03-28 04:22:44

+0

所以...你的代碼是什麼樣的?有許多方法不正確地使用圖像加載/存儲操作,並且沒有辦法知道在沒有看到代碼的情況下你做了哪些操作。 – 2013-03-28 04:33:15

回答

0

我將讓你沒有表現出代碼中的一些假設。因爲你沒有顯示它。我會認爲:

  1. 您使用proper memory coherence operations當你去到顯示這個圖像(是否實際屏幕或在glReadPixels/glGetTexImage操作)。
  2. 您使用正常的渲染命令渲染了這個場景,沒有特殊的三角形排序或任何東西。您沒有使用單獨的渲染命令渲染每個三角形,並在每個三角形之間使用內存一致性操作。

總之,我會假設你的問題實際上是由你的着色引起的。這很可能是由於許多其他事情。但是因爲你沒有設法顯示你的其他代碼,所以我不知道。因此,這個答案實際上可能並不能解決你的問題。但垃圾,垃圾。

從着色器和上面的假設我可以看到的問題其實很簡單:incoherent memory accesses (like image load/store)完全無序的。您執行了圖像寫入操作。因此,除非您採取措施提供這些保證,否則您對此寫入操作沒有任何保證。

是的,你使用了早期片段測試。但這並不意味着片段着色器的不連貫內存訪問順序將以任何特定的順序排列。

考慮一下如果渲染一個三角形會發生什麼,然後在它前面呈現一個完全覆蓋它的三角形。早期的片段測試不會改變任何東西,因爲頂部片段發生在底部片段之後。並且映像加載/存儲不保證任何關於寫入同一像素的順序的任何東西。因此,在寫入頂部三角形之後,寫入底部三角形很可能完成。

據我所知,從這樣的不同片段着色器中對相同像素進行排序是不可能的。即使您在寫完之後發佈了memoryBarrier,但我對規範的閱讀並不表示這將保證寫入順序。

正確的答案是不要這樣做。寫入片段着色器輸出;這就是他們在那裏的原因。

+0

就像我說的,這是一個實驗。我瞭解到除了執行正確渲染所需的早期片段測試之外,還需要額外的邏輯。無論這種功能是否可以用原子或我還沒有發現的東西來複制。目前我沒有時間進行更多的實驗。但是,是的,當我沒有試驗時,我使用的是幀緩衝器和片段輸出。 – ragnar 2013-03-29 21:00:58