Jump to content
  • Advertisement
Sign in to follow this  
FrEEzE2046

Performant way to create a cylinder by a point

This topic is 2619 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
Advertisement
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
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.

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
With the max vertex count at 128 you can make the array that size too.

If you run into an array size limit you can always do multiple iterations with one section of the cylinder per iteration.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!