I'm using directx12. I want to make tessellation for my polygon, for this I wrote 2 simple shaders:
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;
}
here are my vs and 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;
}
To understand the reason, I simplified the shaders as much as possible, I don’t even use the wvp matrix. If I use a vertex shader like this without tessellation, the polygon is rendered
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;
}
if i use my hs and ds the screen is blank. I don't understand why, because they don't do anything at all, because tesselation parameters are 1.0f. I've looked at all the shader examples I could find and I don't see any reason why my shaders aren't working. This is how I compile shaders:
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)
here are some of the pipeline parameters that I changed to set hs and 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 ;
I didn't do anything else in DirectX. Perhaps I need to do some extra work with DirectX to get my shaders to work, or my shaders are written incorrectly (I'm handling all errors, I just skipped that for code brevity)
The problem turned out to be that I had not completely changed the type topology. This is not reflected in the question text. To use tessellation you need to set
D3D12_PRIMITIVE_TOPOLOGY_TYPE::D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH
in the structure field
D3D12_GRAPHICS_PIPELINE_STATE_DESC::PrimitiveTopologyType
and also set
ID3D12GraphicsCommandList::IASetPrimitiveTopology(D3D_PRIMITIVE_TOPO LOGY_3_CONTROL_POINT_PATCHLIST)