Geometry shaders and varying arrays

Hello! This is hopefully a quick one.

Is it possible to pass an array as a varying into a geometry shader from a vertex shader? I’m filling an array with position values in the vertex shader, and then I’m trying to use those positions in the geometry shader to output vertices. Needless to say, it’s not working.

I have this in the vertex shader:


varying vec4 wPositions[7];

... code to fill wPositions with data ...

And this in the geometry shader:


varying vec4 wPositions[7];

for (int i = 0; i < 7; i++) {
     gl_Position = wPositions[i];
     gl_TexCoord[2] = wPositions[i];
     EmitVertex();
     EndPrimitive();
}

In the fragment shader I’m using gl_TexCoord[2] as the position for splatting into a texture map. Basically this code at a high level takes one vertex from the vertex shader and splits it into seven positions (each in a slightly different location), which are then supposed to be passed to and output by the geometry shader, and all seven are splatted with the fragment shader. However, the position data is getting lost somewhere, because all the points are being splatted at (0, 0) in the texture map.

Your problem is that you’ve forgot that the geometry shader works on an entire primitive so it receives an array of all varyings the vertex shader emits so you should rather try something like the following:

varying vec4 wPositions[][7];

for (int i = 0; i < 7; i++) {
     gl_Position = wPositions[0][i];
     gl_TexCoord[2] = wPositions[0][i];
     EmitVertex();
     EndPrimitive();
}

Thank you! That’s exactly what I realized after posting this, and I was trying what you mentioned but I’m still running into problems.

I can’t do this:


varying vec4 wPositions[][7];

because I get the error: “error C7517: OpenGL does not allow multi dimensional arrays”

If I take out the empty brackets, with the rest of the code like yours I get: "error C7011: implicit cast from “float” to “vec4"” on the gl_Position and gl_TexCoord[2] lines.

So I removed the empty brackets and tried this:


gl_Position = vec4(wPositions[i][0], wPositions[i][1], wPositions[i][2], wPositions[i][3]);

which compiles but still doesn’t work because the positions are all (0, 0), same problem as before. Switching the [i] and the [number] when accessing the array doesn’t work either - in fact it gives errors that I’m giving it array indices that are out of bounds.

The way I would suggest doing this is to stop using ARB/EXT_geometry_shader4 and start using core 1.50-style geometry shaders.

Then, you can use interface blocks and not have to create multidimensional arrays.

In your vertex shader:


out VertexData
{
    vec4 wPositions[7];
} outData;

In the geometry shader:


in VertexData
{
    vec4 wPositions[7];
} vert[];

To access a vertex’s data:


vert[0].wPositions[i];

Though to be honest, I don’t understand why you’re doing it this way at all. Whatever computations you were doing in your vertex shader to compute 7 positions could just as easily be done in the geometry shader. And you won’t have to deal with passing arrays and such.

You know what Alfonse, you’re absolutely right. I’m going to try moving the relevant vertex shader stuff over to the geometry shader, and that should fix my problems. It’s going to take some major work to do it, but we’ll see. They are fairly complicated shaders (for real-time caustics), meaning it won’t be a straightforward copy and paste. Worth a try!

Hey it totally worked! It was much easier than I was expecting to move everything to the geometry shader. Here’s a screenshot of the program running so you can see what you helped me with:

I’m working on some pieces of real-time spectral rendering. The piece here is spectral caustics (the rainbows). It sure isn’t real-time yet - only 4 fps in this screenshot - but I’m getting there!

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.