2015-10-08 92 views
0

我在OpenGL中創建了一個使用頂點着色器,幾何着色器和片段着色器的應用程序。跨多個着色器的OpenGL統一

我有一個統一的變量,eyePositionWorld,我想在幾何着色器和片段着色器中使用。

(我渲染verticies的相比eyePositionWorld作爲顏色的位置)

#version 430 

in vec4 vertexPositionModel; 
in vec3 vertexColor; 
in vec3 vertexNormalModel; 

in mat4 modelMatrix; 

uniform mat4 viewMatrix;//World To View 
uniform mat4 projectionMatrix;//View to Projection 

struct fData 
{ 
    vec3 fragColor; 
    vec3 fragPositionWorld; 
    vec3 fragNormalWorld; 
}; 

out fData geomData; 

void main() 
{ 
    gl_Position = projectionMatrix * viewMatrix * modelMatrix * vertexPositionModel; 
    geomData.fragColor = vertexColor; 
    geomData.fragPositionWorld = (modelMatrix * vertexPositionModel).xyz; 
    geomData.fragNormalWorld = (modelMatrix * vec4(vertexNormalModel, 0.0)).xyz; 
} 

幾何着色器

#version 430 

layout(triangles_adjacency) in; 
layout(triangle_strip, max_vertices=3) out; 

struct fData 
{ 
    vec3 fragColor; 
    vec3 fragPositionWorld; 
    vec3 fragNormalWorld; 
}; 

uniform vec3 eyePositionWorldGeomShader; 

in fData geomData[]; 
out fData fragData; 

void main() { 
    gl_Position = gl_in[0].gl_Position; 
    fragData = geomData[0]; 
    fragData.fragColor = gl_in[0].gl_Position.xyz - eyePositionWorldGeomShader; 
    EmitVertex(); 

    gl_Position = gl_in[2].gl_Position; 
    fragData = geomData[2]; 
    fragData.fragColor = gl_in[2].gl_Position.xyz - eyePositionWorldGeomShader; 
    EmitVertex(); 

    gl_Position = gl_in[4].gl_Position; 
    fragData = geomData[4]; 
    fragData.fragColor = gl_in[4].gl_Position.xyz - eyePositionWorldGeomShader; 
    EmitVertex(); 

    EndPrimitive(); 
} 

片段着色器

頂點着色器

#version 430 

struct fData 
{ 
    vec3 fragColor; 
    vec3 fragPositionWorld; 
    vec3 fragNormalWorld; 
}; 

in fData fragData; 

uniform vec4 ambientLight; 
uniform vec3 lightPositionWorld; 
uniform vec3 eyePositionWorld; 
uniform bool isLighted; 

out vec4 color; 

void main() 
{ 
    if (!isLighted) 
    { 
     color = vec4(fragData.fragColor, 1.0); 
    } 
    else 
    { 
     vec3 lightVectorWorld = normalize(lightPositionWorld - fragData.fragPositionWorld); 

     float brightness = clamp(dot(lightVectorWorld, normalize(fragData.fragNormalWorld)), 0.0, 1.0); 
     vec4 diffuseLight = vec4(brightness, brightness, brightness, 1.0); 

     vec3 reflectedLightVectorWorld = reflect(-lightVectorWorld, fragData.fragNormalWorld); 
     vec3 eyeVectorWorld = normalize(eyePositionWorld - fragData.fragPositionWorld); 

     float specularity = pow(clamp(dot(reflectedLightVectorWorld, eyeVectorWorld), 0.0, 1.0), 40) * 0.5; 
     vec4 specularLight = vec4(specularity, specularity, specularity, 1.0); 

     //Maximum Distance of All Lights 
     float maxDist = 55.0; 

     float attenuation = clamp((maxDist - length(lightPositionWorld - fragData.fragPositionWorld))/maxDist, 0.0, 1.0); 

     color = (ambientLight + (diffuseLight + specularLight) * attenuation) * vec4(fragData.fragColor, 1.0); 
    } 
} 

C++代碼(在m_eyePositionULm_eyePositionGeomShaderUL都只是裝載glGetUniformLocation

glUniform3fv(m_eyePositionUL, 1, &m_camera.getPosition()[0]); 
glUniform3fv(m_eyePositionGeomShaderUL, 1, &m_camera.getPosition()[0]); 

我怎麼只能上傳一個統一的,以OpenGL和兩個幾何着色器和頂點着色器使用它?

回答

1

這有點令人驚訝,但OpenGL很容易。你所要做的就是在兩個着色器中使用相同的統一名稱!

然後只需在該統一位置下載一次即可。

在你的幾何着色器中用uniform vec3 eyePositionWorldGeomShader;替換uniform vec3 eyePositionWorld;,並保持片段着色器中的統一名稱相同。

然後就不要上載其他均勻的,所以你的C++代碼將只是

glUniform3fv(m_eyePositionUL, 1, &m_camera.getPosition()[0]);