Parameters 通过细分在HLSL中传递参数

Parameters 通过细分在HLSL中传递参数,parameters,directx,shader,hlsl,tessellation,Parameters,Directx,Shader,Hlsl,Tessellation,我的问题希望很简单,但我似乎无法获得正确的数据流。问题是如何将纹理坐标和法线数据从顶点着色器通过细分阶段(外壳和域着色器)传递到像素着色器进行渲染 我遇到的问题是,在使用细分之前,数据可以简单地从顶点传递到像素着色器。这两个着色器之间现在有多个步骤:面片常数函数、外壳着色器和域着色器 如果有人能给我一些关于如何通过这些部分传递数据的见解,如果可能的话,也许能给我一些快速的伪代码来演示,我将非常感谢。如果您需要更多信息或我当前的代码(即使它不工作),请告诉我 额外信息:程序是用C++使用Direc

我的问题希望很简单,但我似乎无法获得正确的数据流。问题是如何将纹理坐标和法线数据从顶点着色器通过细分阶段(外壳和域着色器)传递到像素着色器进行渲染

我遇到的问题是,在使用细分之前,数据可以简单地从顶点传递到像素着色器。这两个着色器之间现在有多个步骤:面片常数函数、外壳着色器和域着色器

如果有人能给我一些关于如何通过这些部分传递数据的见解,如果可能的话,也许能给我一些快速的伪代码来演示,我将非常感谢。如果您需要更多信息或我当前的代码(即使它不工作),请告诉我


额外信息:程序是用C++使用DirectX 11 API编写的,使用HLSL.</P> < P>这是我用来创建镶嵌的代码,我隐藏了一些代码,只显示了你需要的代码。 ps:tess_因子是常数缓冲区的一个参数

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;
}
HS\u输出数据HS\u补丁(InputPatch ip,uint pid:SV\u PrimitiveID)
{
HS_输出_数据返回;
浮动苔丝=苔丝系数;
返回边[0]=返回边[1]=返回边[2]=苔丝;
ret.inside=tess;//与边相同的值
返回ret;
}
[域名(“tri”)]
[分区(“整数”)]//整数、分数偶数、分数奇数
[输出拓扑(“三角形连续波”)]
[输出控制点(3)]
[patchconstantfunc(“hs_补丁”)]
HS_输出HS(InputPatch ip,单元索引:SV_OutputControlPointID)
{
HS_输出ret;
ret.pos=ip[index].pos;
返回ret;
}
[域名(“tri”)]
顶点通过ds(HS输出数据输入,浮点3 dl:SV域位置,常数
输出补丁(bp)
{
顶点通过ret;
ret.pos=bp[0]。pos*dl.x+bp[1]。pos*dl.y+bp[2]。pos*dl.z;
返回ret;
}

顶点、外壳、域和像素着色器的常量缓冲区是分开的。在应用程序的代码隐藏中,在使用的常量缓冲区中设置参数:

ID3D11DeviceContext::PSSetConstantBuffers
ID3D11DeviceContext::HSGetConstantBuffers
第一个函数将常量缓冲区设置为像素着色器使用。外壳着色器的第二个集。但在您的情况下,必须使用结构向前传递参数。这是我只传递颜色的代码:

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;
}
struct VERTEX\u过程
{
浮动4位置:SV_位置;
浮动4颜色:颜色;
};
结构HS_输出_数据
{
浮动4位:WORLDPOS;
浮动4颜色:颜色;
浮动边[3]:SV_TessFactor;//在本例中不使用
float inside:SV_insideetessfactor;//在本例中不使用
};
HS_输出数据HS_补丁(InputPatch ip,uint pid:SV_PrimitiveID)
{
HS_输出_数据返回;
ret.color=ip[pid].color;//将颜色传递给forward
返回ret;
}

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

我认为您需要一个简单的示例,因为您没有解释错误消息之类的情况

这里有一个:

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

我还建议您在编译着色器代码时启用调试信息。

这样你就可以知道你的着色器程序出了什么问题,也许你可以自己马上解决


我只想在下面发表评论,但不知怎么的,评论按钮消失了。

我没有投反对票,但我认为你的问题有点宽泛;尝试一下,展示你已经尝试过的,其他人将能够更好地提供帮助。嗨,对不起,我不想发布我的任何代码,因为它跨越多个文件,而且大小相当大。只是希望在使用tesselation时对着色器的数据流有一些了解。