• Advertisement
Sign in to follow this  

Multiple subdivision of an icosahedron using HLSL Geometry Shader

This topic is 2318 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

I've asked this question on stackoverflow.com earlier, but didn't get an answer.
Currently I'm subdividing an icosahedron once by using the following Geometry Shader:

[source lang="cpp"][maxvertexcount(128)]
void gs(triangle VS_OUT gin[3], inout TriangleStream<GS_OUT> s)
{
float3 m0 = .5f * (gin[0].pos_l + gin[1].pos_l),
m1 = .5f * (gin[2].pos_l + gin[1].pos_l),
m2 = .5f * (gin[0].pos_l + gin[2].pos_l);

float3 v[6];
v[0] = gin[0].pos_l;
v[1] = m0;
v[2] = m2;
v[3] = m1;
v[4] = gin[2].pos_l;
v[5] = gin[1].pos_l;

GS_OUT gout;
for (int i = 0; i < 5; ++i)
{
gout.pos_h = mul(float4(v, 1.f), g_mat_wvp);
s.Append(gout);
}
s.RestartStrip();

gout.pos_h = mul(float4(v[1], 1.f), g_mat_wvp);
s.Append(gout);

gout.pos_h = mul(float4(v[5], 1.f), g_mat_wvp);
s.Append(gout);

gout.pos_h = mul(float4(v[3], 1.f), g_mat_wvp);
s.Append(gout);
}[/source]

However, I want to specify the subdivision level. Is there any possibility to call the Shader again with the outputed verticies or do I need to follow an other approach?

Share this post


Link to post
Share on other sites
Advertisement
There is no way to do it directly in the pipeline without streaming the data out first - either you can use stream output, or possibly output the data in the pixel shader to render targets or a UAV. Then you would re-inject the geometry to the pipeline in the same manner.

Have you considered using the tessellation stages in D3D11? They are made for doing exactly what you are trying to do, and should be able to let you select the tessellation level in a programmatic way.

Share this post


Link to post
Share on other sites
Have you considered using the tessellation stages in D3D11? They are made for doing exactly what you are trying to do, and should be able to let you select the tessellation level in a programmatic way.

Thanks for your reply. I need to run this in D3D10 as well. So, unfortunately, I cannot use tessellation.

Share this post


Link to post
Share on other sites
I've solved the problem in the following way:

[source lang="cpp"][maxvertexcount(128)]
void gs(triangle VS_OUT gin[3], inout TriangleStream<GS_OUT> s)
{
if (g_subdivs != 0 && g_subdivs <= MAX_SUBDIVISION_LEVEL)
{
uint level_count = (uint)pow(2, g_subdivs);
float3 u = (gin[1].pos_l - gin[0].pos_l) / level_count,
w = (gin[2].pos_l - gin[0].pos_l) / level_count,
v = gin[0].pos_l;

for (int level = level_count; level > 0; --level)
{
GS_OUT gout;
gout.pos_h = mul(float4(normalize(v), 1.f), g_mat_wvp);
s.Append(gout);

float3 p = v;
uint vertex_count = level + 1;

for (uint vertex = 1; vertex < vertex_count; ++vertex)
{
gout.pos_h = mul(float4(normalize(p + u), 1.f), g_mat_wvp);
s.Append(gout);

gout.pos_h = mul(float4(normalize(p += w), 1.f), g_mat_wvp);
s.Append(gout);
}

v += u;
s.RestartStrip();
}
}
else
{
[unroll]
for (uint i = 0; i < 3; ++i)
{
GS_OUT gout;
gout.diff = gin.diff;
gout.pos_h = mul(float4(gin.pos_l, 1.f), g_mat_wvp);

s.Append(gout);
}
}
}

[/source]

Share this post


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

  • Advertisement