DirectX11有多种D3D11_PRIMITIVE_TOPOLOGY
typedef enum D3D11_PRIMITIVE_TOPOLOGY {
D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED = 0,
D3D11_PRIMITIVE_TOPOLOGY_POINTLIST = 1,
D3D11_PRIMITIVE_TOPOLOGY_LINELIST = 2,
D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP = 3,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST = 4,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 5,
D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = 10,
D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = 11,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = 12,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = 13,
D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = 33,
D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST = 34,
D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST = 35,
D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST = 36,
D3D11_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST = 37,
D3D11_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST = 38,
D3D11_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST = 39,
D3D11_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST = 40,
D3D11_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST = 41,
D3D11_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST = 42,
D3D11_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST = 43,
D3D11_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST = 44,
D3D11_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST = 45,
D3D11_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST = 46,
D3D11_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST = 47,
D3D11_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST = 48,
D3D11_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST = 49,
D3D11_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST = 50,
D3D11_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST = 51,
D3D11_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST = 52,
D3D11_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST = 53,
D3D11_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST = 54,
D3D11_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST = 55,
D3D11_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST = 56,
D3D11_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST = 57,
D3D11_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST = 58,
D3D11_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST = 59,
D3D11_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST = 60,
D3D11_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST = 61,
D3D11_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST = 62,
D3D11_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST = 63,
D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = 64
} D3D11_PRIMITIVE_TOPOLOGY;
我们在渲染粗糙Beam顶点时,用的是D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP。然而,若我们要使用细分Shader,我们只能使用33以后的
D3D11_PRIMITIVE_TOPOLOGY 。这迫使我们设计一个新的VertexBuffer结构来支持不断开地渲染TRIANGLESTRIP。
使用IndexBuffer技术个复杂的过程,难以维护与扩展。添加重复的顶点也会造成冗余。
DirectX11细分Shader的使用经验也告诉我们,三维贝塞尔平滑一条线需要的4个控制点,所以我们还需要设计一个新的Vertex结构来求出这4个控制点,同时不干扰以上的进行。
这个Vertex结构就是
struct VS_INPUT
{
float4 vCP : CP;// control point
float4 vSP : SP;// source point
};
VertexBuffer结构依然类是之前的TRIANGLESTRIP结构,ID3D11DeviceContext::IAGetPrimitiveTopology Method设为D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST这时,我们一次渲染4个顶点设为V0,V1,V2,V3。V0.SP, V0.CP, V2.CP, V2.SP这四个向量维护一条贝塞尔曲线,V1.SP, V1.CP, V3.CP, V3.SP维护另外一条贝塞尔曲线。
domain shader 代码:
//--------------------------------------------------------------------------------------
// Domain Shader
//--------------------------------------------------------------------------------------
float4 BernsteinBasis(float t)
{
float invT = 1.0f - t;
return float4( invT * invT * invT,
3.0f * t * invT * invT,
3.0f * t * t * invT,
t * t * t );
}
//--------------------------------------------------------------------------------------
float4 EvaluateBezier( const OutputPatch<HS_OUTPUT, OUTPUT_PATCH_SIZE> bezpatch,
float4 BasisU,
float2 BasisV )
{
float4 Value = float4(0,0,0,0);
Value = BasisV.x * (
bezpatch[0].vSP * BasisU.x +
bezpatch[0].vCP * BasisU.y +
bezpatch[2].vCP * BasisU.z +
bezpatch[2].vSP * BasisU.w );
Value += BasisV.y * (
bezpatch[1].vSP * BasisU.x +
bezpatch[1].vCP * BasisU.y +
bezpatch[3].vCP * BasisU.z +
bezpatch[3].vSP * BasisU.w );
return Value;
}
[domain("quad")]
DS_OUTPUT DSMain( HS_CONSTANT_DATA_OUTPUT input,
float2 UV : SV_DomainLocation,
const OutputPatch<HS_OUTPUT, OUTPUT_PATCH_SIZE> bezpatch )
{
float4 BasisU = BernsteinBasis( UV.x );
float2 LinearV = float2(UV.y, 1 - UV.y);
float4 WorldPos = EvaluateBezier( bezpatch, BasisU, LinearV );
DS_OUTPUT Output;
Output.vPosition = WorldPos;
return Output;
}
下篇讲述SP的计算。