I am looking for an easy solution for passing information between shader stages when adding additional shader stages. Right now I am using the "out" keyword to pass data from for example vertex to fragment shader. On the fragment shader of cause I am using "in" to receive the data.

The problem I have is the following: The variable name MUST be the same. So "out vec3 test;" can only be received by variable "in vec3 test;". When optionally plug in a geometry shader to duplicate triangles, I would like to receive the outputting data from the vertex shader "in vec3 test" and pass it to the fragment shader "out vec3 test". And here the program crashes... because both variables names are "test"

Here the Vertex shader code:

#version 430
layout(location = 0) in vec3 vertexPosition;

out vec3 test;

void main()
    gl_Position = vec4(vertexPosition, 1.0f);
    test = vec3(1.0f, 2.0f, 3.0f); //this is just a test!

The Fragment shader code:

#version 430

in vec3 test;
out vec4 color;

void main()
    color = vec4(test, 1.0f); 

So the last shader (geometry shader) should be able to plug in if wanted, without changing the vertex or fragment shader.

The Geometry shader code:

#version 430 core
layout (triangles) in;
layout (triangle_strip, max_vertices = 30) out;

in vec3 test[];  
out vec3 test;  // this does not work (name already exists)

void main()
    vec4 position0 = gl_Position[0];
    vec4 position1 = gl_Position[1];
    vec4 position2 = gl_Position[2];      

    for(uint i = 0; i < 10; ++i)
        gl_Position = position0 + vec4(i,0,0,0);   
        test = test[0]; //this of cause does not work... (I just want to pass this information)
        gl_Position = position1 + vec4(i,0,0,0);    
        test = test[1]; //this of cause does not work... 
        gl_Position = position2 + vec4(i,0,0,0);    
        test = test[2]; //this of cause does not work... 


This geometry shader should copy the input triangle 10 times and pass the "varying" data from vertex to fragment shader.
So the goal is that the vertex and fragment shader do not need to be changed when adding or leaving out the geometry shader.

We would like to do stuff like that for example to enable/disable layered rendering, adding a tessellation shader when wanted. Right now we need to write several shaders for the same thing. For example when having the option of enable/disable layered rendering and enable/disable tessellation there are 2^2 = 4 possibilities. This means we need to write the same shader 4 times. With this approach we only need to write it once and just plug in the shader stages when needed.

I am also interested in dynamically read out type and values of passed data. So ask within the geometry shader which variables are passed and then forward them to the next stage. With this approach we would be able to write one geometry shader which can be plugged between several other shaders.

What possibilities do we have to generate such a system?


1 Answer 1


GLSL allows a location to be assigned to each in/out variables then the names can be anything you want.

Here is an example:

Vertex shader:

layout(location=0) out vec3 test;

Geometery shader:

// as long as the location numbers match, the names don't matter
layout(location=0) in vec3 testIn; 
layout(location=0) out vec3 testOut;

Fragment shader:

 // location 0 gets testOut from geom shader
layout(location=0) in vec3 randomName;

If the geometry shader is removed from this example then the fragment shader will get the output of the vertex shader location 0 output.

  • $\begingroup$ thanks a lot! is there a way to ask for the location type? and how mush locations are send? $\endgroup$
    – Thomas
    Sep 13, 2021 at 13:00
  • $\begingroup$ There is no way to ask for the locations and types inside GLSL. It all has to be hard coded. $\endgroup$
    – pmw1234
    Sep 13, 2021 at 13:03
  • $\begingroup$ @Thomas: "There is no way to ask for the locations and types inside GLSL." This is actually incorrect, as of GL 4.4. Through the program introspection API, you can ask a program for its input and output locations. However, since this works at the program level, you would have to be putting each shader in its own program to query the locations of its inputs/outputs. $\endgroup$ Sep 14, 2021 at 1:14
  • $\begingroup$ @NicolBolas okay thank you! This gives me a lot of possibilities to manage a flexible shader exchange modul. Thanks! $\endgroup$
    – Thomas
    Sep 14, 2021 at 7:53
  • $\begingroup$ oops haha, my answer was kind of circular as I was thinking of querying the $\endgroup$
    – pmw1234
    Sep 14, 2021 at 13:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.