Sign in to follow this  
FrEEzE2046

Multiple subdivision of an icosahedron using HLSL Geometry Shader

Recommended Posts

I've asked this question on [url="http://stackoverflow.com/questions/7795800/multiple-subdivision-of-an-icosahedron-using-hlsl-geometry-shader"]stackoverflow.com[/url] 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[i], 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
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
[quote name='Jason Z' timestamp='1318913783' post='4873759']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.[/quote]
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[i].diff;
gout.pos_h = mul(float4(gin[i].pos_l, 1.f), g_mat_wvp);

s.Append(gout);
}
}
}

[/source]

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