使用Tessellation在HLSL中传递参数

时间:2012-12-13 21:13:17

标签: parameters directx shader hlsl tessellation

我的问题很有希望非常简单,但我似乎无法正确地获取数据流。问题是如何将顶点着色器中的纹理坐标和法线数据通过曲面细分阶段(Hull和Domain着色器)传递到像素着色器以进行渲染。

我遇到的问题是在使用tesselation之前,数据可以简单地从顶点传递到像素着色器。现在这两个着色器之间有多个步骤,一个补丁常量函数用于外壳着色器,然后是域着色器。

如果有人能够让我深入了解如何通过这些部分传递数据,并且如果可能的话可能会有一些快速伪代码来演示它,我会非常感激。如果您需要更多信息或我当前的代码(即使它不起作用),请告诉我。

额外信息:该程序使用HLSL使用DirectX 11 api以C ++编写。

3 个答案:

答案 0 :(得分:0)

这是我用来创建曲面细分的代码,我隐藏了一些代码,只显示您需要的代码。 ps:tess_factor是常量缓冲区的参数。

HS_OUTPUT_DATA hs_patch(InputPatch<VERTEX_PASS, 3> ip, uint pid : SV_PrimitiveID)
{
HS_OUTPUT_DATA ret;
float tess = tess_factor;
ret.edges[0] = ret.edges[1] = ret.edges[2] = tess;
ret.inside = tess; // same value that edges
return ret;
}

[domain("tri")]
[partitioning("integer")] // integer, fractional_even, fractional_odd
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
[patchconstantfunc("hs_patch")]
HS_OUTPUT hs(InputPatch<VERTEX_PASS, 3> ip, uint index : SV_OutputControlPointID)
{
HS_OUTPUT ret;
ret.pos = ip[index].pos;
return ret;
}

[domain("tri")]
VERTEX_PASS ds(HS_OUTPUT_DATA input, float3 dl : SV_DomainLocation, const     
OutputPatch<HS_OUTPUT, 3> bp)
{
    VERTEX_PASS ret;
    ret.pos = bp[0].pos * dl.x + bp[1].pos * dl.y + bp[2].pos * dl.z;
    return ret;
}

答案 1 :(得分:0)

Vertex,Hull,Domain和Pixel Shader的常量缓冲区是分开的。在应用程序背后的代码中,将参数设置在您使用的常量缓冲区中:

ID3D11DeviceContext::PSSetConstantBuffers
ID3D11DeviceContext::HSGetConstantBuffers

第一个函数将常量缓冲区设置为Pixel Shader使用。 Hull Shader的第二套。但在您的情况下,您必须使用结构向前传递参数。这是我传递颜色的代码:

struct VERTEX_PASS
{
    float4 pos : SV_POSITION;
    float4 color : COLOR;
};

struct HS_OUTPUT_DATA
{
    float4 pos : WORLDPOS;
    float4 color : COLOR;
    float edges[3] : SV_TessFactor; // not using in this example
    float inside : SV_InsideTessFactor; // not using in this example
};

HS_OUTPUT_DATA hs_patch(InputPatch<VERTEX_PASS, 3> ip, uint pid : SV_PrimitiveID)
{
    HS_OUTPUT_DATA ret;
    ret.color = ip[pid].color; // pass the color to forward
    return ret;
}

纹理坐标是相同的想法,但颜色在所有顶点都是常量,在纹理坐标的情况下,在域着色器阶段,您必须像计算最终顶点位置一样计算新的UV坐标。

答案 2 :(得分:0)

我认为你需要一个简单的例子,因为你没有像错误信息那样解释你的情况。

这是一个:http://www.rastertek.com/dx11tut38.html

作者简要解释了代码的每一行,您可以看到细分阶段的一部分,以了解如何在渲染管道的每个阶段之间定义数据结构。

我还建议您在启用调试信息的情况下编译着色器代码。 http://msdn.microsoft.com/zh-tw/library/windows/desktop/ff476261(v=vs.85).aspx

有了这个你可以知道你的着色器程序出了什么问题,也许你可以马上解决它。

我想在下面发表评论但不知何故评论按钮消失了。