cbuffer UniformBlock0 : register(b0) { float4x4 model_view_matrix; float4x4 proj_matrix; float4x4 model_view_proj_matrix; float3x3 normal_matrix; float3 color; float3 view_dir; float3 tess_factor; }; // ============================================================================= // Hull Shader // ============================================================================= struct HSInput { float3 PositionWS : POSITION; float3 NormalWS : NORMAL; }; struct HSOutput { float3 PositionWS : POSITION; }; struct HSTrianglePatchConstant { float EdgeTessFactor[3] : SV_TessFactor; float InsideTessFactor : SV_InsideTessFactor; float3 NormalWS[3] : NORMAL; }; HSTrianglePatchConstant HSPatchConstant(InputPatch patch) { float3 roundedEdgeTessFactor = tess_factor; float roundedInsideTessFactor = 3; float insideTessFactor = 1; HSTrianglePatchConstant result; // Edge and inside tessellation factors result.EdgeTessFactor[0] = roundedEdgeTessFactor.x; result.EdgeTessFactor[1] = roundedEdgeTessFactor.y; result.EdgeTessFactor[2] = roundedEdgeTessFactor.z; result.InsideTessFactor = roundedInsideTessFactor; // Constant data result.NormalWS[0] = patch[0].NormalWS; result.NormalWS[1] = patch[1].NormalWS; result.NormalWS[2] = patch[2].NormalWS; return result; } [domain("tri")] [partitioning("fractional_odd")] [outputtopology("triangle_ccw")] [outputcontrolpoints(3)] [patchconstantfunc("HSPatchConstant")] HSOutput HSMain( InputPatch patch, uint id : SV_OutputControlPointID ) { HSOutput output; output.PositionWS = patch[id].PositionWS; return output; } // ============================================================================= // Geometry Shader // ============================================================================= struct GSVertexInput { float3 PositionWS : POSITION; float3 NormalWS : NORMAL; }; struct GSVertexOutput { float4 PositionCS : SV_POSITION; }; [maxvertexcount(6)] void GSMain( triangle GSVertexInput input[3], inout LineStream output ) { float3 P0 = input[0].PositionWS.xyz; float3 P1 = input[1].PositionWS.xyz; float3 P2 = input[2].PositionWS.xyz; GSVertexOutput vertex; // Totally hacky... P0.z += 0.001; P1.z += 0.001; P2.z += 0.001; float4 Q0 = mul(proj_matrix, float4(P0, 1.0)); float4 Q1 = mul(proj_matrix, float4(P1, 1.0)); float4 Q2 = mul(proj_matrix, float4(P2, 1.0)); // Edge 0 vertex.PositionCS = Q0; output.Append(vertex); vertex.PositionCS = Q1; output.Append(vertex); output.RestartStrip(); // Edge 1 vertex.PositionCS = Q1; output.Append(vertex); vertex.PositionCS = Q2; output.Append(vertex); output.RestartStrip(); // Edge 2 vertex.PositionCS = Q2; output.Append(vertex); vertex.PositionCS = Q0; output.Append(vertex); output.RestartStrip(); }