Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm using a small geometry shader to build a "ribbon" from a set of points. For each point, I create 4 vertices that represent a section of the ribbon:

[maxvertexcount(4)]
void    GS( point GS_Input v[1],
            inout TriangleStream<PS_Input> ptStream )
{
    float4  vertices[4];
    vertices[0] = float4(v[0].pos.x - 2, 0, v[0].pos.z + 2, 1);
    vertices[1] = float4(v[0].pos.x + 2, 0, v[0].pos.z + 2, 1);
    vertices[2] = float4(v[0].pos.x - 2, 0, v[0].pos.z - 2, 1);
    vertices[3] = float4(v[0].pos.x + 2, 0, v[0].pos.z - 2, 1);

    PS_Input ov = (PS_Input)0;
    for (int i = 0; i < MVC; i++)
    {
        ov.posW = mul(vertices[i], g_world);
        ov.posH = mul(vertices[i], g_wvp);
        ov.normalW = mul(float4(v[0].normal, 0), g_world);
        ov.color = v[0].color;
        ptStream.Append(ov);
    }
}

As mentioned on the MSDN: "A geometry shader generating triangle strips will start a new strip on every invocation", and because of this, I don't get a ribbon, all I get is a set of quads, just like as if I was doing some particle billboarding. Is there any way to circumvent that in order to keep the same strip from on invocation to the next ?

share|improve this question
add comment

2 Answers 2

up vote 3 down vote accepted

No, there is not. Geometry shaders, like most shader stages, are separate from one another.

What you seem to want, since you specified DX11, is tessellation. That allows you to take a "patch" and subdivide it. A "patch" could be a string of points of some arbitrary length, which you would "subdivide" into multiple subdivisions.

share|improve this answer
add comment

It is possible in some sense. If you use a primitive type with adjacency information (D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ) you can construct quads that fit together nicely, even if they aren't technically in the same strip. I've used this technique with some success myself.

Please excuse the awesome ASCII art; '.' are points, and '|' and '\' are edges.

In your shader, the GS invocations go something like this (1 per point):

   [.] .  .  .  .
    . [.] .  .  .
    .  . [.] .  .
    .  .  . [.] .
    .  .  .  . [.]
giving:
    |  |  |  |  |

Instead, you'd want to use a linestrip with adjacency (1 invocation per 4 points, overlapping). The same diagram would then be:

[.  .  .  .] .  .  .
 . [.  .  .  .] .  .
 .  .[ .  .  .  .] .
 .  .  . [.  .  .  .]
giving:
   |\||\||\||\||\|  

So, you construct a quad (for a 2D strip) with each invocation using the average of the first two and last two points [EDIT: I'm overcomplicating things: no averaging is actually required, just draw a quad between any two adjacent points on each invocation]. The code might look something like this (I'm not entirely sure what your original code is trying to do):

[maxvertexcount(8)]
void    GS( lineadj GS_Input v[4],
            inout TriangleStream<PS_Input> ptStream )
{
    float4 middlePos = 0.5*(v[0].pos+v[1].pos);
    float4  vertices[4];

    vertices[0] = float4(middlePos.x - 2, 0, middlePos.z + 2, 1);
    vertices[1] = float4(middlePos.x + 2, 0, middlePos.z + 2, 1);
    vertices[2] = float4(middlePos.x - 2, 0, middlePos.z - 2, 1);
    vertices[3] = float4(middlePos.x + 2, 0, middlePos.z - 2, 1);
    //construct and emit first 4 PS_input's
    middlePos = 0.5*(v[1].pos+v[2].pos);
    vertices[0] = float4(middlePos.x - 2, 0, middlePos.z + 2, 1);
    vertices[1] = float4(middlePos.x + 2, 0, middlePos.z + 2, 1);
    vertices[2] = float4(middlePos.x - 2, 0, middlePos.z - 2, 1);
    vertices[3] = float4(middlePos.x + 2, 0, middlePos.z - 2, 1);
    //construct and emit another 4 PS_input's
}

Also, you'll probably want to duplicate the first and triplicate the last points in your list for this to behave similarly to the original point list.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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