【NoisyHeart的炼成】Part3:Beam的平滑问题

来源:互联网 发布:手机文字排版软件 编辑:程序博客网 时间:2024/06/08 10:21

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的计算。



0 0
原创粉丝点击