2013-09-25 21 views
8

所以我正在瀏覽橙皮書(第3版),並且在第9章中我遇到了關於不變限定符的一段。它說:關於OpenGL不變限定符的困惑

不變預選賽指示編譯器和鏈接忽略的表達和功能沒有直接關係到輸出的計算。

這段話來自後兩個代碼相似的片段:

uniform mat4 MVPmatrix; 
// ... 

in vec4 MCVertex; 
// ... 

a(); // does not modify gl_Position, MVP or MCVertex 

// ... 
// Transform vertex to clip space 
gl_Position = MVP * MCVertex; 

uniform mat4 MVPmatrix; 
// ... 

invariant gl_Position; 
in vec4 MCVertex; 
// ... 

a(); // does not modify gl_Position, MVP or MCVertex 

// ... 
// Transform vertex to clip space 
gl_Position = MVP * MCVertex; 

這本書,然後繼續說:

第一種情況可能會或不管用什麼不相關的函數,都不能以完全相同的方式計算變換後的位置或表達式鏈接到着色器。如果使用多遍算法多次渲染相同的幾何圖形,這可能會導致渲染問題。

哪個讓我困惑。如果a()決不會影響計算變換位置所涉及的變量,那麼計算如何變化? (以及invariant有什麼幫助?)。並且提到第一句話時,他們說「忽略不相關的功能」究竟意味着什麼?他們只是沒有被執行?

回答

8

invariant的目的是爲了確保您所做的計算始終會產生相同的結果,無論着色器優化器對着色器做什麼(特別是跨多個着色器編譯)。

我發現橙皮書的措辭很差(和誤導,正如你所指出的那樣)。的GLSL規範(語言1.2)第4.6節更清晰:

在本節中,方差是指由不同程序中的相同的表達式得到 不同的值的可能性。對於 示例,假設兩個頂點着色器在不同的程序中,每個着色器在兩個着色器中都設置爲 gl_Position,並且輸入 值與該表達式的值相同。由於獨立編譯了兩個着色器,因此 可能是 着色器運行時分配給gl_Position的 值不完全相同。在這個例子中,這可能會導致多通道算法中的幾何對齊 問題。通常,允許着色器之間的這種差異 。當特定輸出變量不存在這種差異時,該變量被認爲是不變的。

它繼續解釋invariant限定符可以保證避免這個問題。

+0

我不認爲這回答了原點兩個問題。並且報價塊既不是 – suitianshi

+0

@suitianshi:OP想要理解不變量,並繼續剖析橙皮書對此有何評論。橙皮書的內容基本上可以被認爲是錯誤的。所以我選擇從原始來源,GLSL規範回答。原始問題試圖理解錯誤的陳述。你想要什麼正確的答案? – Bahbar

+0

我發現了一個描述爲什麼我們有時需要「不變」的頁面。它表示多通道問題可能是由cpu指令重新排序引起的(還有一些其他的問題,對不起,我不記得它清楚又找不到內容)。例如,如果我使用相同的着色器程序渲染兩次三角形,但在兩次傳遞過程中我得到了一次睡眠或購物,那麼產生的兩個三角形可能不會重疊(當然,偏移量可能非常小)。其實我已經閱讀了GLSL規範,但仍然感到困惑。 – suitianshi

3

invariant關鍵字(簡而言之就是與Bahbar的更詳細的答案形成對比),更多關於可能出現的非常微妙的計算差異,正如您所提到的那樣,多重幾何通過。

下面是一個例子:在屏幕上繪製一個任意的,怪異的(使其更難)三角形。柵格化器獲得標準化的頂點並計算它佔據的所有片段,然後在其上運行片段着色器。現在,想象一下你想在它上面畫出另一個三角形,但3小時後,當你的電腦被淹沒時,溫度下降,你在此期間吃午餐。然後重新編譯着色器,然後砰...

所有這些可能會影響光柵化器。着色器優化可能會啓動並對輸出進行小幅更改。雖然技術上仍然正確,但結果不一定必須與第一個三角形完全相同,並且「問題」將是剩下的第一個像素。

invariant確保採取可能較慢的方法。我不是司機架構師,但是總的來說,這可能意味着一些額外的狀態重置,清理或者有時候狀態堆棧推/拉。只有這樣你才能得到「乾淨」的計算狀態,只要你的硬件沒問題,結果應該完全一樣。