This is my Hull Shader, I get "warning X3554: unknown attribute <attr_name_here>, or attribute invalid for this statement" on every attribute above the main function, as well as "error X3658: 'main': InputPatch inputs can only be used in the domain shaders and a hull shader's patch constant function" on the InputPatch parameter in the main function:
struct HullShaderInput
{
float4 wPos : WPOSITION;
float4 position : SV_POSITION;
float3 colour : COLOUR;
float3 normal : NORMAL;
float2 uv : UV;
};
struct HullShaderConstDataOutput
{
float EdgeTessFactor[3] : SV_TessFactor;
float InsideTessFactor : SV_InsideTessFactor;
};
struct HullShaderOutput
{
float4 wPos : WPOSITION;
float4 position : SV_POSITION;
float3 colour : COLOUR;
float3 normal : NORMAL;
float2 uv : UV;
};
cbuffer cBuff : register(b0)
{
float4x4 world;
float4x4 view;
float4x4 projection;
float4 camPos;
}
//cbuffer iBuff : register(b1)
//{
// float4 objPos;
//}
#define NUM_CONTROL_POINTS 3
float calcTessFactor(float3 vertP1, float3 vertP2)
{
float edgeLen = distance(vertP1, vertP2);
float edgeCamDist = distance((vertP1+vertP2)/2, camPos.xyz);
// Not based on objects size on the screen
// To give more accurate approximation, multiply with the screen height in pixels and an FOV factor (1 at 90 deg, increasing at lower FOV),
//and divide by the allowed edge length in pixels.
return clamp((edgeLen)/(edgeCamDist), 1.0f, 63.0f); // Using max=63 because of fractional_odd partitioning
}
HullShaderConstDataOutput CalcHSPatchConstants
( InputPatch<HullShaderInput, NUM_CONTROL_POINTS> ip,
uint i : SV_PrimitiveID )
{
HullShaderConstDataOutput output;
// This function should calculate the factors based on distance to camera, so the constant value is just temporary... I think
//output.EdgeTessFactor[0] = output.EdgeTessFactor[1] = output.EdgeTessFactor[2] = output.InsideTessFactor = 32;
// Anyways, this should have a decent approximation for realistic tessellation factors based on distance to camera
// That is, if every "ip" represents a triangle, and "i" represents a point on said triangle
output.EdgeTessFactor[i] = calcTessFactor(ip[i].wPos.xyz, ip[(i+1)%3].wPos.xyz);
output.InsideTessFactor = (output.EdgeTessFactor[0]+output.EdgeTessFactor[1]+output.EdgeTessFactor[2])/3;
return output;
}
[domain("tri")]
[partitioning("fractional_odd")]
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
[patchconstantfunc("HullShaderConstDataOutput")]
HullShaderOutput main
( InputPatch<HullShaderInput, NUM_CONTROL_POINTS> ip,
uint i : SV_OutputControlPointID )
{
HullShaderOutput output;
output.wPos = ip[i].wPos;
output.position = ip[i].position;
output.normal = ip[i].normal;
output.uv = ip[i].uv;
return output;
}
This is my Domain Shader, I get "warning X3554" on [domain("tri")] and "error X3658" on on the main function's OutputPatch parameter:
struct DomainShaderConstDataInput
{
float EdgeTessFactor[3] : SV_TessFactor;
float InsideTessFactor : SV_InsideTessFactor;
};
struct DomainShaderInput
{
float4 wPos : WPOSITION;
float4 position : SV_POSITION;
float3 colour : COLOUR;
float3 normal : NORMAL;
float2 uv : UV;
};
struct DomainShaderOutput
{
float4 wPos : WPOSITION;
float4 position : SV_POSITION;
float3 colour : COLOUR;
float3 normal : NORMAL;
float2 uv : UV;
};
cbuffer cBuff : register(b0)
{
float4x4 world;
float4x4 view;
float4x4 projection;
float4 camPos;
};
#define NUM_CONTROL_POINTS 3
[domain("tri")]
DomainShaderOutput main
( DomainShaderConstDataInput input, float3 barycentric : SV_DomainLocation,
const OutputPatch<DomainShaderInput, NUM_CONTROL_POINTS> patch )
{
DomainShaderOutput output;
output.wPos = patch[0].wPos*barycentric.x + patch[1].wPos*barycentric.y + patch[2].wPos*barycentric.z;
output.normal = normalize(patch[0].normal*barycentric.x + patch[1].normal*barycentric.y + patch[2].normal*barycentric.z);
output.uv = patch[0].uv*barycentric.x + patch[1].uv*barycentric.y + patch[2].uv*barycentric.z;
output.position = mul(mul(output.wPos, view), projection);
return output;
}
What am I doing wrong here?
Edit:
So, it turns out that my Hull and Domain shaders were using Shader Model 4, when 5 is required. Still, I can't compile them yet, because for some reason the HullShaderConstDataOutput attribute's entrypoint can't be found in the main function.
So, it turns out that my Hull and Domain shaders were using Shader Model 4, when 5 is required. It is now fixed. I also had the issue of referring to the constData struct and not the constData function, so that also sucks. Anyways, I can now render tessellated surfaces based on distance to the camera and the edge length for a fixed window size and FOV==90.