2014-02-20 46 views
2

我想進行凹凸/普通/視差貼圖,但爲此目的,我需要多紋理 - 每次使用2個紋理 - 一個用於顏色,另一個用於高度貼圖。但是這項任務的成就似乎是荒謬的問題。OpenGL着色器:統一變量計數不正確

我有一個頂點着色器下面的代碼:

#version 330 core 

    /* 0: in 
    * 1: out 
    * 2: uniform 
    */ 

    // 0: in 
    layout (location = 0) in vec3 v_vertexPos; 
    layout (location = 1) in vec2 v_vertexTexCoord; 

    // 1: out 
    out vec2 f_vertexTexCoord; 

    // 2: uniform 
    uniform mat4 vertexMvp = mat4(1.0f); 

    void main() 
    { 
     f_vertexTexCoord = v_vertexTexCoord; 
     gl_Position = vertexMvp * vec4(v_vertexPos, 1.0f); 
    } 

和片段下列操作之一:

#version 330 core 

    /* 0: in 
    * 1: out 
    * 2: uniform 
    */ 

    // 0: in 
    in vec2 f_vertexTexCoord; 

    // 1: out 
    layout (location = 0) out vec4 f_color; 

    // 2: uniform 
    uniform sampler2D cTex; 
    uniform sampler2D hTex; 

    // #define BUMP 

    void main() 
    { 
     vec4 colorVec = texture2D(cTex, f_vertexTexCoord); 

    #ifdef BUMP 
     vec4 bumpVec = texture2D(hTex, f_vertexTexCoord); 
     f_color = vec4(mix(bumpVec.rgb, colorVec.rgb, colorVec.a), 1.0); 
    #else 
     f_color = texture2D(cTex, f_vertexTexCoord); 
    #endif 
    } 

着色器被編譯並連接到着色器程序。該程序然後鏈接,然後使用。 glGetActiveUniform唯一報告的活動統一變量是頂點着色器的統一vertexMvp和片段的cTex。無法識別hTex並查詢其位置,結果爲-1。圖形卡支持GL_ARB_multitexture OpenGL擴展(支持最高4.3的OpenGL版本)。

測試了提供的簡單多紋理示例here,該示例僅使用了存儲頂點之一定義了片段着色器。這個例子像一個魅力。

有什麼建議嗎?

+1

如果未使用制服,則着色器編譯器將優化它們。在這種情況下,你會得到-1作爲他們的位置。 –

+0

完全正確的答案。 – Ivan

+0

這沒有錯。你有着實際使用'hTex'預處理過的着色器部分。鏈接器將確定制服在鏈接程序中處於不活動狀態,並且不會分配統一的位置。這不是一個優化的過程,也不是編譯器要做的事情。 –

回答

4

「GLSL編譯器和鏈接器儘可能高效,因此,他們盡最大努力消除不影響舞臺輸出的代碼,因此,在着色器文件中定義的統一數據不必是隻有在統一碼用於影響舞臺輸出的編碼時,制服本身才可以改變舞臺的輸出

因此,一個由完全鏈接的程序稱爲「主動」制服;由原始着色器指定的任何其他制服不活動,不活動的制服不能用於程序中的任何事情。 - OpenGL.org

由於您的片段着色器中沒有定義BUMP,因此您的代碼中未使用hTex,因此它不是活動的制服。這是預期的行爲。