Multiple subdivision of an icosahedron using HLSL Geometry Shader

Started by
2 comments, last by FrEEzE2046 12 years, 5 months ago
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?
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.
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.
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]

This topic is closed to new replies.

Advertisement