3D Line / Tube in geometry shader

Hi,
I’m cooking up a shader based 3D Line thingy.
It basically works with some limitations:

Thoughts and help welcome!

Still to do:

  • Smooth normals!
  • Why is “Maxvertexcount” in geometry shader limited to 64? (Or is it my machine?)
  • Buffer for thickness and individial line segments
  • Caps
  • There are some glitches going on with shadows. I guess it’s an issue with clipping…not sure

shaders.zip (10.0 KB)

Related:

8 Likes

Tubby_Test.zip (11.3 KB)

Update with Caps.

Here is a fixed version that has correct depth output and writes some other values that the pixel shader might need. you could think of adding tangents, if you want to use normal maps.

TubbyShader.zip (10.7 KB)

it also outputs one strip, and not individual triangles, which reduces the vertex output count.

That is important for the shader output limit, it is 1024 32-bit values. so the amount of vertices you can emit is 1024/vertexstride. That can vary, depending on what the pixel shader needs. you can set all stream values in the geometry shader and depending on the material features, your max count will be limited as the output datatype will be dynamically compiled.

you might also need to pass in the up vector along with the points, to avoid flipping.

4 Likes

Re: Vertexstride, I already passed this on to Michael, seemed legit:

https://www.gamedev.net/forums/topic/600141-limit-on-maxvertexcount-gs/

Have you considered using geometry shader instancing? Assuming you are using D3D11 hardware, you can simply execute multiple copies of the geometry shader for each primitive. Then you can process one half of your data in one instance and the other half in the second instance - you would then just need to use the SV_GSInstanceID system value semantic in the shader to select the proper subset of data to produce. You can have up to 32 instances created for each primitive, so you could effectively up the limit to 1024*32.

1 Like

Thanks, very interesting, this discussion leads to this: How To Instance a Geometry Shader - Win32 apps | Microsoft Learn

you can add an [instance(N)] attribute, where N is a number between 1 and 32. And then use SV_GSInstanceID to emit more vertices. But not 100% sure if the SDSL parser knows about that. I’ve never tried it.

I have now and it works :)

TubbyShaderGSInstancing.zip (10.8 KB)

The shader signature should look like this:

[instance(32)]
[maxvertexcount(64)]
stage void GSMain(line Input input[2], inout TriangleStream<Output> triangleStream, uint gsInstanceID : SV_GSInstanceID)

3 Likes

That escalated quickly!

Anyway here is the optimized and fixed version, with unoptimized caps:
Tubby.zip (11.2 KB)

4 Likes

Looks great, they only seem to be missing setting the depth value, I’d recommend using the AppendVertex() method for them as well to be sure that all vertex shader variables are set…

3 Likes