使用 HLSL 几何着色器对二十面体进行多重细分

发布于 2024-12-10 02:06:52 字数 1036 浏览 0 评论 0原文

目前,我正在使用以下几何着色器对二十面体进行一次细分:

[maxvertexcount(8)]
void gs(triangle VS_OUT gin[3], inout TriangleStream<GS_OUT> s)
{
    //        p1  
    //       /  \
    //      /    \
    //     m0 --- m1
    //    / \    / \
    //   /   \  /   \
    //  p0 -- m2 -- p2

    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);
}

但是,我想指定细分级别。是否有可能使用输出的顶点再次调用着色器,或者我是否需要采用其他方法?

Currently I'm subdividing an icosahedron once by using the following Geometry Shader:

[maxvertexcount(8)]
void gs(triangle VS_OUT gin[3], inout TriangleStream<GS_OUT> s)
{
    //        p1  
    //       /  \
    //      /    \
    //     m0 --- m1
    //    / \    / \
    //   /   \  /   \
    //  p0 -- m2 -- p2

    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);
}

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦里泪两行 2024-12-17 02:06:52

我已经通过以下方式解决了它:

[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);
        }
    }
}

I've solved it in the following way:

[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);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文