| 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<HSInput, 3> 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<HSInput, 3> 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<GSVertexOutput> 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(); | |
| } |