2012-02-10 67 views
62

我看到很多不同的片段着色的,片段着色器如何知道用於像素顏色的變量?

#version 130 

out vec4 flatColor; 

void main(void) 
{ 
    flatColor = vec4(0.0,1.0,0.0,0.5); 
} 

而且它們都使用了「出彩」不同的變量(在這種情況下flatColor)。那麼OpenGL如何知道你想要做什麼?

我猜這是可行的,因爲flatColor是唯一定義爲out的變量,但您可以添加更多out變量不是嗎?或者只是會崩潰?


其實,作爲一個測試,我只是跑這樣的:

#version 330 

in vec2 TexCoord0; 

uniform sampler2D TexSampler; 

out vec4 x; 
out vec4 y; 

void main() 
{ 
    y = texture2D(TexSampler, TexCoord0.xy); 
} 

它好工作我是否使用xy


此外,我們有一個預定義的gl_FragColor。有什麼區別,爲什麼人們通常會堅持使用自己的變量?

回答

124

此外,我們有一個預定義的gl_FragColor。

讓我們從這個開始。不,你不要有預定義的gl_FragColor。這是從核心OpenGL 3.1和以上刪除。除非你使用兼容性(在這種情況下,你的3.30着色器應該在頂部顯示#version 330 compatibility),否則你不應該使用它。

現在回到用戶定義的片段着色器輸出。但首先,快速比喻一下。

還記得,在頂點着色器中,你有輸入嗎?這些輸入代表頂點屬性索引,您傳遞給glVertexAttribPointerglEnableVertexAttribArray等的數字?你設置哪個輸入從哪個屬性拉。在GLSL 3.30,使用此語法:

layout(location = 2) in color; 

這臺color頂點着色器輸入來自屬性位置2.前3.30(或不ARB_explicit_attrib_location),你就必須要麼glBindAttrbLocation之前設置此明確鏈接或查詢屬性索引的程序glGetAttribLocation。如果你沒有明確提供一個屬性位置,GLSL將任意指定一個位置(即:以實現定義的方式)。

在着色器中設置它幾乎總是最好的選擇。

在任何情況下,片段着色器輸出的工作方式幾乎完全相同。片段着色器可以寫入multiple output colors,它們本身被映射到multiple buffers in the framebuffer。因此,您需要指出哪個輸出轉到哪個片段輸出顏色。

該過程從片段輸出位置值開始。它的設置非常相似頂點着色器輸入地點:

layout(location = 1) out secColor; 

也有API函數glBindFragDataLocationglGetFragDataLocation,這類似於glBindAttribLocationglGetAttribLocation

如果你不做任何明確的任務,實現通常會分配給你的輸出變量中的一個位置0。但是,OpenGL標準不要求此行爲,所以你不應該依賴於它的。

現在公平起見,當你使用兩個輸出沒有得到不同的輸出位置時,你的程序應該有失敗的鏈接。可能發生的事情是,你的編譯器優化了你沒有寫出來的編譯器,所以當它檢查鏈接器錯誤時,它會忘記它。

+3

希望我可以給+1。壯觀的答案。我想知道如何片段輸出位置工作。 :) – kevintodisco 2012-02-10 06:07:00

+0

啊..所以他們不推薦使用'gl_FragColor',而是讓你更靈活地選擇要寫入哪個緩衝區?說得通。再次感謝! – mpen 2012-02-10 06:08:51

+3

@Mark:「棄用」意味着「您仍然可以使用它,但可能會在更高版本中刪除它。」 「刪除」意味着*刪除*。它們是有區別的。那些在GL 3.0中被標記爲廢棄的內容在3.1中被刪除了**(除了幾件事情之外)。 – 2012-02-10 06:58:55

6

我想指定此爲OpenGLES 3.1它使用GLSL_ES_3.10 link

§4.4.2

如果只有一個單一的輸出[在片段着色器],則 位置不需要指定,在這種情況下,它默認爲 零。

相關問題