Hi guys!
I recently just started implementing tessellation for my terrain system, but it isn't quite working as I expected, nothing shows up. Further down I am going to give you some code which includes the tessellation, nothing fancy, as I said, I just got started. I don't expect you to read it all, just that if you spot something you find weird/wrong, please say so as it may help me.
Without implementing the tessellation, the terrain renders perfectly, but when trying to implement the tessellation, nothing is shown. PS. One interesting thing is that when rendering without tessellation, I use: D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, but when tessellating, I understood that I had to use D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST, well according to my shader file.
Shader (Simple):
cbuffer ConstantObjectBuffer : register (b0)
{
matrix worldMatrix;
};
cbuffer ConstantFrameBuffer : register (b1)
{
matrix viewMatrix;
matrix projectionMatrix;
float3 eyepos;
float cppad;
float4 lightvec;
float4 lightcol;
float FogStart;
float FogEnd;
float2 __space;
float3 FogColor;
float shadows;
float SpecularIntensity;
float3 pad3;
float4 SpecularColor;
}
//***************************************************//
// VERTEX SHADER //
//***************************************************//
struct VOut
{
float4 position : SV_POSITION;
float2 texcoord : TEXCOORD;
float access : ACCESS;
float3 NormalW : NORMWORLD;
float4 depthPosition : TEXTURE0;
};
struct GlobalIn
{
float4 position : POSITION;
float4 normal : NORMAL;
float2 texcoord : TEXCOORD;
};
Texture2D t_map : register(t0);
SamplerState ss;
VOut VShader(GlobalIn input)
{
VOut output;
input.position.w = 1.0f;
output.texcoord = input.texcoord;
// Calculate the position of the vertex against the world, view, and projection matrices.
output.position = mul(input.position, worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
output.NormalW = mul(float4(input.normal.xyz,0), mul(worldMatrix, viewMatrix));
// Store the position value in a second input value for depth value calculations.
output.depthPosition.xyz = mul(float4(input.position.xyz,1), mul(worldMatrix, viewMatrix)).xyz;
// Per Vertex lighting
float4 norm = normalize(input.normal);
output.access = saturate(dot(norm, lightvec));
return output;
}
//***************************************************//
// HULL SHADER //
//***************************************************//
struct HOutput
{
float edges[3] : SV_TessFactor;
float inside : SV_InsideTessFactor;
};
#define tessellationAmount 12.0f
HOutput ColorPatchConstantFunction(InputPatch<VOut, 3> inputPatch, uint patchId : SV_PrimitiveID)
{
HOutput output;
// Set the tessellation factors for the three edges of the triangle.
output.edges[0] = 12.0f;
output.edges[1] = 12.0f;
output.edges[2] = 12.0f;
// Set the tessellation factor for tessallating inside the triangle.
output.inside = 12.0f;
return output;
}
[domain("tri")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
[patchconstantfunc("ColorPatchConstantFunction")]
VOut HShader(InputPatch<VOut, 3> patch, uint pointId : SV_OutputControlPointID, uint patchId : SV_PrimitiveID)
{
VOut output;
// Set the x for this control point as the output x.
output.position = patch[pointId].position;
output.texcoord = patch[pointId].texcoord;
output.access = patch[pointId].access;
output.NormalW = patch[pointId].NormalW;
output.depthPosition = patch[pointId].depthPosition;
return output;
}
//***************************************************//
// DOMAIN SHADER //
//***************************************************//
[domain("tri")]
VOut DShader(HOutput input, float3 uvwCoord : SV_DomainLocation, const OutputPatch<VOut, 3> patch)
{
float3 vertexPosition;
VOut output;
// Determine the position of the new vertex.
vertexPosition = uvwCoord.x * patch[0].position + uvwCoord.y * patch[1].position + uvwCoord.z * patch[2].position;
// Calculate the position of the new vertex against the world, view, and projection matrices.
output.position = mul(float4(vertexPosition, 1.0f), worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
// Send the input color into the pixel shader.
output.texcoord = patch[0].texcoord;
output.access = patch[0].access;
output.NormalW = patch[0].NormalW;
output.depthPosition = patch[0].depthPosition;
return output;
}
//***************************************************//
// PIXEL SHADER //
//***************************************************//
struct POut
{
float4 Diffuse : SV_Target0;
float4 Depth : SV_Target1;
float4 Normals : SV_Target2;
float4 Lighting : SV_Target3;
};
POut PShader(VOut input)
{
POut output;
// Depth
output.Depth = float4(input.depthPosition.xyz, 1.0f);
// Normals
output.Normals = float4(normalize(input.NormalW), 1);
output.Diffuse = float4(1, 1, 1, 1);
output.Lighting = float4(lightcol.rgb * input.access, 1.0f);
output.Lighting = float4(1, 1, 1, 1);
return output;
}
C++:
Before Rendering:
devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST);
Shader Creation:
D3DX11CompileFromFile(finals.c_str(), 0, 0, "VShader", "vs_5_0", CE_DBG, 0, 0, &VS, &vserrors, &HR);
D3DX11CompileFromFile(finals.c_str(), 0, 0, "PShader", "ps_5_0", CE_DBG, 0, 0, &PS, &pserrors, &HR);
D3DX11CompileFromFile(finals.c_str(), 0, 0, "HShader", "hs_5_0", CE_DBG, 0, 0, &HS, &hserrors, &HR);
D3DX11CompileFromFile(finals.c_str(), 0, 0, "DShader", "ds_5_0", CE_DBG, 0, 0, &DS, &dserrors, &HR);
// Error Checking
Applying Shader:
devcon->VSSetShader(pVS, 0, 0);
devcon->HSSetShader(pHS, 0, 0);
devcon->DSSetShader(pDS, 0, 0);
devcon->PSSetShader(pPS, 0, 0);
devcon->IASetInputLayout(pLayout);
Rendering:
// Set constant buffers
devcon->DrawIndexed(bf.IndexCount, 0, 0);
PIX:
I hope that I have supplied you with enough information, as I haven't found the solution yet, but is still trying.
Thank you, as always GameDev.