Sign in to follow this  
FrEEzE2046

Performant way to create a cylinder by a point

Recommended Posts

Currently I'm creating cylinders from a point representing the center position of the cylinder. In addition, I specify the radius, segment count and height of a cylinder. Due to performance issues I want to do that in a Gemetry Shader.

The following code (reduced to the position relevant parts) shows my shader code:

[source lang="cpp"]struct VS_OUT
{
float radius : RADIUS;
float height : HEIGHT;
uint segments : SEGMENTS;
float3 pos_l : POSITION;
};

struct GS_OUT
{
float4 pos_h : SV_POSITION;
};


[maxvertexcount(128)]
void gs(point VS_OUT gin[1], inout TriangleStream<GS_OUT> s)
{
const float pi = 3.14159265f;

// Side faces
float phi = 2 * pi / gin[0].segments;
for (uint i = 0; i <= gin[0].segments; ++i)
{
float4 pos_l = float4(gin[0].pos_l.x + gin[0].radius * sin(phi * i), gin[0].pos_l.y,
gin[0].pos_l.z + -gin[0].radius * cos(phi * i), 1.f);

GS_OUT gout;
gout.pos_h = mul(pos_l, g_mat_wvp);
s.Append(gout);

pos_l.y += gin[0].height;
gout.pos_h = mul(pos_l, g_mat_wvp);
s.Append(gout);
}

// Bottom face
s.RestartStrip();
for (int i = gin[0].segments; i >= 0; --i)
{
float4 pos_l = float4(gin[0].pos_l.x + gin[0].radius * sin(phi * i), gin[0].pos_l.y,
gin[0].pos_l.z + -gin[0].radius * cos(phi * i), 1.f);

GS_OUT gout;
gout.pos_h = mul(pos_l, g_mat_wvp);
s.Append(gout);

pos_l.xz = 0;
gout.pos_h = mul(pos_l, g_mat_wvp);
s.Append(gout);
}

// Top face
s.RestartStrip();
for (uint i = 0; i <= gin[0].segments; ++i)
{
float4 pos_l = float4(gin[0].pos_l.x + gin[0].radius * sin(phi * i),
gin[0].pos_l.y + gin[0].height, gin[0].pos_l.z + -gin[0].radius * cos(phi * i), 1.f);

GS_OUT gout;
gout.pos_h = mul(pos_l, g_mat_wvp);
s.Append(gout);

pos_l.xz = 0;
gout.pos_h = mul(pos_l, g_mat_wvp);
s.Append(gout);
}
}[/source]

Is there a way to get this more performant? Thanks in advance.

Share this post


Link to post
Share on other sites
Surely the fastest option is to create a single static cylinder model (or maybe 2-3 with varying poly counts), and then transform that to the appropriate size and shape in the vertex shader.

If you want to optimize that GS code I believe you shouldn't need to calculate each point so many times - you can cache them in an array. Using sincos() might speed it up a bit too.

Share this post


Link to post
Share on other sites
[quote name='Adam_42' timestamp='1318865376' post='4873481']If you want to optimize that GS code I believe you shouldn't need to calculate each point so many times - you can cache them in an array.[/quote]
How can I cache them in an array? I would need to create a dynamic array for doing that and that's not possible in HLSL. Or do I miss something?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this