我使用的是directx12。我想为我的多边形进行镶嵌,为此我编写了 2 个简单的着色器:
struct Vertex{
float3 Position : POSITION;
float4 Color : COLOR;
};
struct tesOutput{
float edgeTessellationFactor[3] : SV_TessFactor;
float insideTessellationFactor : SV_InsideTessFactor;
};
tesOutput ConstantHS(InputPatch< Vertex, 3> patch, uint patchID : SV_PrimitiveID ){
tesOutput output;
output.edgeTessellationFactor[0] = 1.0f;
output.edgeTessellationFactor[1] = 1.0f;
output.edgeTessellationFactor[2] = 1.0f;
output.insideTessellationFactor = 1.0f;
return output;
}
[domain("tri")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
[patchconstantfunc("ConstantHS")]
Vertex hull(InputPatch< Vertex, 3> patch, uint cPoint : SV_OutputControlPointID){
return patch[cPoint];
}
struct DomainOut{
float4 Position : SV_POSITION;
float4 Color : COLOR;
};
[domain("tri")]
DomainOut domain(OutputPatch< Vertex, 3> patch, tesOutput tessInput, float3 UVW : SV_DomainLocation ){
DomainOut output;
float4 _1=float4(patch[0].Position.xyz,1);
float4 _2=float4(patch[1].Position.xyz,1);
float4 _3=float4(patch[2].Position.xyz,1);
output.Position=_1 * UVW.x +
_2 * UVW.y +
_3 * UVW.z ;
output.Position=float4(output.Position.xyz, 1.0f);
output.Color = float4(1.0f, 0.0f, 1.0f, 1.0f);
return output;
}
这是我的对比和ps:
struct vertex{
float3 pos : POSITION;
float4 color : COLOR;
};
vertex main(float3 position : POSITION, float4 color : COLOR) {
vertex output;
output.pos = position;
output.color = float4(1.0f, 0.0f, 1.0f, 1.0f);
return output;
}
struct VS_OUTPUT
{
float4 pos: SV_POSITION;
float4 color: COLOR;
};
float4 main(VS_OUTPUT input) : SV_TARGET
{
return input.color;
}
为了理解原因,我尽可能地简化了着色器,我什至不使用 wvp 矩阵。如果我使用像这样的顶点着色器而不进行曲面细分,则会渲染多边形
struct vertex{
float4 pos : SV_POSITION;
float4 color : COLOR;
};
vertex main(float3 position : POSITION, float4 color : COLOR) {
vertex output;
output.pos = float4(position, 1);
output.color = float4(1.0f, 0.0f, 1.0f, 1.0f);
return output;
}
如果我使用 hs 和 ds,则屏幕为空白。我不明白为什么,因为他们根本不做任何事情,因为曲面细分参数是1.0f。我已经查看了我能找到的所有着色器示例,但没有发现我的着色器无法工作的任何原因。这就是我编译着色器的方式:
D3DCompileFromFile(L"Shaders/VertexShader.hlsl", nullptr, nullptr, "main", "vs_5_0", D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &DX12.Shaders.vShader, &error)
D3DCompileFromFile(L"Shaders/TeselationShader.hlsl", nullptr, nullptr, "hull", "hs_5_0", D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &DX12.Shaders.hShader, &error)
D3DCompileFromFile(L"Shaders/TeselationShader.hlsl", nullptr, nullptr, "domain", "ds_5_0", D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &DX12.Shaders.dShader, &error)
D3DCompileFromFile(L"Shaders/ColorShader.hlsl", nullptr, nullptr, "main", "ps_5_0", D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &DX12.Shaders.pShader, &error)
以下是我更改的一些用于设置 hs 和 ds 的管道参数:
pipeLineDesc.VS={DX12.Shaders.vShader->GetBufferPointer(), DX12.Shaders.vShader->GetBufferSize()};
pipeLineDesc.PS={DX12.Shaders.cShader->GetBufferPointer(), DX12.Shaders.cShader->GetBufferSize()};
pipeLineDesc.HS={DX12.Shaders.hShader->GetBufferPointer(), DX12.Shaders.hShader->GetBufferSize()};
pipeLineDesc.DS={DX12.Shaders.dShader->GetBufferPointer(), DX12.Shaders.dShader->GetBufferSize()};
pipeLineDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
pipeLineDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH ;
我没有在 DirectX 中做任何其他事情。也许我需要使用 DirectX 做一些额外的工作才能让我的着色器正常工作,或者我的着色器编写不正确(我正在处理所有错误,为了代码简洁起见我只是跳过了它)
问题原来是我没有完全改变类型拓扑。这没有反映在问题文本中。要使用曲面细分,您需要设置
D3D12_PRIMITIVE_TOPOLOGY_TYPE::D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH
在结构体字段D3D12_GRAPHICS_PIPELINE_STATE_DESC::PrimitiveTopologyType中,同时设置
ID3D12GraphicsCommandList::IASetPrimitiveTopology(D3D_PRIMITIVE_TOPO LOGY_3_CONTROL_POINT_PATCHLIST)