0
\$\begingroup\$

My program is a rain particle system. After processing a list of positions of rain particles, I passed them to the geometry shader for generating a billboard for each position.

If I use a simple method to generate the billboard, (it is a rectangle, not really a billboard), it work well and I can see them in the render target. This simple method proves that the input positions for the geometry shader are right. The below HLSL source implement this simple billboard.

[maxvertexcount(4)]
void GSMAIN( point GS_INPUT input[1], inout TriangleStream<PS_INPUT> SpriteStream )
{
    //Transform to view space
    float4 viewposition = mul(float4(input[0].position, 1.0f), WorldViewMatrix);

    // Emit two new triangles
    for (int i = 0; i < 4; i++)
    {
        // Transform to clip space
        //g_positions is an array of four deltal vectors in the form: (-scale, +scale, 0, 0)..
        output.position = mul(viewposition + g_positions[i], ProjMatrix);
        output.texcoords = g_texcoords[i]; 
        output.color = color;

        SpriteStream.Append(output);
    }
    SpriteStream.RestartStrip();
}

But if I changed to create a real billboard, it shows nothing. My method is based the velocity vector of rain drop. The implementation is in below:

[maxvertexcount(4)]
void GSMAIN( point GS_INPUT input[1], inout TriangleStream<PS_INPUT> SpriteStream )
{
    PS_INPUT output;

    //Velocity of raindrop = Rate + original velocity
    //The billboard will stays along this vector
    float3 velocityVector =  input[0].speed.xyz/FrameRate + TotalVelocity;

    //ViewPosition: the position of camera
    GenRainSpriteVertices(input[0].position, velocityVector, ViewPosition, pos);

    for(int i = 0; i < 4; i++)
    {
        output.position = mul(float4(pos[i], 1.0f), WorldViewProjMatrix);
        output.texcoords = g_texcoords[0];
        output.color = color;
        SpriteStream.Append(output);
    }
}

///////////////////////////////////////////////////
//The function generating billboard from
//1. Point Position
//2. Eye Position
//3. Velocity vector
///////////////////////////////////////////////////
void GenRainSpriteVertices(float3 worldPos, float3 velVec, float3 eyePos, out float3           outPos[4])
{
    float height = g_SpriteSize / 2.0;
    float width = height / 10.0;

    velVec = normalize(velVec);
    float3 eyeVec = eyePos - worldPos;
    float3 eyeOnVelVecPlane = eyePos - ((dot(eyeVec, velVec)) * velVec);
    float3 projectedEyeVec = eyeOnVelVecPlane - worldPos;
    float3 sideVec = normalize(cross(projectedEyeVec, velVec));

    outPos[0] = worldPos - (sideVec * 0.5*width);
    outPos[1] = outPos[0] + (sideVec * width);
    outPos[2] = outPos[0] + (velVec * height);
    outPos[3] = outPos[2] + (sideVec * width);
}

I tried to use Nsight and Graphics Diagnostics in VS2012 to debug, and all of them show that the geometry shader generated the right vertices. The following pictures are from Visual Studio and Nsight, which present the result after the geometry shader finished its job. enter image description here

And the next result is from Nsight: enter image description here

For some reason, the generated vertices in the geometry shader are discarded in the pixel shader. Why might this be?

\$\endgroup\$
  • 2
    \$\begingroup\$ Is it possible the geometry is being created with the wrong winding order (so the triangles are being removed by back-face culling)? \$\endgroup\$ – GuyRT Feb 26 '14 at 15:10
  • \$\begingroup\$ @GuyRT: Just want to break out into tears. Thanks so much. You help me alot. I really appreciate it. \$\endgroup\$ – khanhhh89 Feb 26 '14 at 15:19
4
\$\begingroup\$

The fact that something is rendered when you use your "simple method" and the geometry can be seen in Nsight led me to guess that the triangles were being back-faced culled. This is because the winding order of the vertices you create disagrees with the culling mode you are using (to put it another way, all your triangles are now facing away from the camera).

You could either disable back-face culling for this effect or (probably better) reverse the winding order of your created geometry.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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