1cbuffer UniformBlock0 : register(b0)
2{
3  float4x4 model_view_matrix;
4  float4x4 proj_matrix;
5  float4x4 model_view_proj_matrix;
6  float3x3 normal_matrix;
7  float3   color;
8  float3   view_dir;
9  float3   tess_factor;
10};
11
12// =============================================================================
13// Hull Shader
14// =============================================================================
15struct HSInput {
16  float3 PositionWS : POSITION;
17  float3 NormalWS   : NORMAL;
18};
19
20struct HSOutput {
21  float3 PositionWS : POSITION;
22};
23
24struct HSTrianglePatchConstant {
25  float  EdgeTessFactor[3] : SV_TessFactor;
26  float  InsideTessFactor  : SV_InsideTessFactor;
27  float3 NormalWS[3]       : NORMAL;
28};
29
30HSTrianglePatchConstant HSPatchConstant(InputPatch<HSInput, 3> patch)
31{
32  float3 roundedEdgeTessFactor = tess_factor;
33  float  roundedInsideTessFactor = 3;
34  float  insideTessFactor = 1;
35
36  HSTrianglePatchConstant result;
37
38  // Edge and inside tessellation factors
39  result.EdgeTessFactor[0] = roundedEdgeTessFactor.x;
40  result.EdgeTessFactor[1] = roundedEdgeTessFactor.y;
41  result.EdgeTessFactor[2] = roundedEdgeTessFactor.z;
42  result.InsideTessFactor  = roundedInsideTessFactor;
43
44  // Constant data
45  result.NormalWS[0] = patch[0].NormalWS;
46  result.NormalWS[1] = patch[1].NormalWS;
47  result.NormalWS[2] = patch[2].NormalWS;
48
49  return result;
50}
51
52[domain("tri")]
53[partitioning("fractional_odd")]
54[outputtopology("triangle_ccw")]
55[outputcontrolpoints(3)]
56[patchconstantfunc("HSPatchConstant")]
57HSOutput HSMain(
58  InputPatch<HSInput, 3>  patch,
59  uint                    id : SV_OutputControlPointID
60)
61{
62  HSOutput output;
63  output.PositionWS = patch[id].PositionWS;
64  return output;
65}
66
67// =============================================================================
68// Geometry Shader
69// =============================================================================
70struct GSVertexInput {
71  float3 PositionWS : POSITION;
72  float3 NormalWS   : NORMAL;
73};
74
75struct GSVertexOutput {
76  float4 PositionCS : SV_POSITION;
77};
78
79[maxvertexcount(6)]
80void GSMain(
81  triangle GSVertexInput            input[3],
82  inout LineStream<GSVertexOutput>  output
83)
84{
85
86  float3 P0 = input[0].PositionWS.xyz;
87  float3 P1 = input[1].PositionWS.xyz;
88  float3 P2 = input[2].PositionWS.xyz;
89
90  GSVertexOutput vertex;
91  // Totally hacky...
92  P0.z += 0.001;
93  P1.z += 0.001;
94  P2.z += 0.001;
95  float4 Q0 = mul(proj_matrix, float4(P0, 1.0));
96  float4 Q1 = mul(proj_matrix, float4(P1, 1.0));
97  float4 Q2 = mul(proj_matrix, float4(P2, 1.0));
98
99  // Edge 0
100  vertex.PositionCS = Q0;
101  output.Append(vertex);
102  vertex.PositionCS = Q1;
103  output.Append(vertex);
104  output.RestartStrip();
105
106  // Edge 1
107  vertex.PositionCS = Q1;
108  output.Append(vertex);
109  vertex.PositionCS = Q2;
110  output.Append(vertex);
111  output.RestartStrip();
112
113  // Edge 2
114  vertex.PositionCS = Q2;
115  output.Append(vertex);
116  vertex.PositionCS = Q0;
117  output.Append(vertex);
118  output.RestartStrip();
119}
120