簡體   English   中英

跨多個着色器的OpenGL統一

[英]OpenGL Uniform Across Multiple Shaders

我已經在OpenGL中創建了一個使用Vertex Shader,Geometry Shader和Fragment Shader的應用程序。

我有一個統一變量eyePositionWorld ,我想同時在Geometry Shader和Fragment Shader中使用。

(我呈現相比於所述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並在“幾何着色器”和“頂點着色器”中使用它?

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

然后,只需在該統一位置下上傳一次即可。

更換uniform vec3 eyePositionWorldGeomShader; 帶有uniform vec3 eyePositionWorld; 在“幾何着色器”中,並在“片段着色器”中使統一名稱保持相同。

然后不要上傳其他Uniform,這樣您的C ++代碼就可以

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM