DX11 Tesslator例子解析

例程来自于DXSDK sample——simpleBezier11

  1. 原始顶点64个,float3格式,分为4个quad(平均每个Quad有16个控制点)

    // Control point for a Bezier patch
        struct BEZIER_CONTROL_POINT {
            float m_vPosition[3];
        };
    
        // Simple Bezier patch for a Mobius strip
        // 4 patches with 16 control points each
        const BEZIER_CONTROL_POINT g_MobiusStrip[64] = {
            { 1.0f, -0.5f, 0.0f },
            { 1.0f, -0.5f, 0.5f },
            { 0.5f, -0.3536f, 1.354f },
           ...
          }

     

  2. Vert shader很简单,直接输出输入的控制点

    1. struct VS_CONTROL_POINT_INPUT {
          float3 vPosition        : POSITION;
      };
      
      struct VS_CONTROL_POINT_OUTPUT {
          float3 vPosition        : POSITION;
      };
      VS_CONTROL_POINT_OUTPUT BezierVS( VS_CONTROL_POINT_INPUT Input ) {
          VS_CONTROL_POINT_OUTPUT Output;
      
          Output.vPosition = Input.vPosition;
      
          return Output;
      }

       

  3. Hull shader:主要有两个作用,传输控制点(得到VS传入的控制点,也可在此新生成新控制点);生成domain shader所需参数(SV_TessFactor,SV_InsideTessFactor)。每个Patch运行一次。

(详见:http://msdn.microsoft.com/en-us/library/windows/desktop/ff476339%28v=vs.85%29.aspx)

SV_TessFactor定义

TypeInput Topology
float[4]quad patch
float[3]tri patch
float[2]isoline

SV_InsideTessFactor定义

TypeInput Topology
float[2]quad patch
floattri patch
unusedisoline
          partitioning可以为 integer, fractional_even, fractional_odd, or pow2.用来定义Tesslator scheme
          
          Topology可以为line, triangle_cw, triangle_ccw
          
struct HS_CONSTANT_DATA_OUTPUT {
    float Edges[4] : SV_TessFactor;
    float Inside[2] : SV_InsideTessFactor;
    };

    struct HS_OUTPUT {
    float3 vPosition : BEZIERPOS;
    };
    [domain("quad")]
    [partitioning(BEZIER_HS_PARTITION)]
    [outputtopology("triangle_cw")]
    [outputcontrolpoints(OUTPUT_PATCH_SIZE)] // HS功能1,输出控制点
    [patchconstantfunc("BezierConstantHS")] // 功能2,提供patch constant data给 fixed function tessellator,特别是TessFactor,对不同domain定义不同
    HS_OUTPUT BezierHS( InputPatch<VS_CONTROL_POINT_OUTPUT, INPUT_PATCH_SIZE> p, uint i : SV_OutputControlPointID, uint PatchID : SV_PrimitiveID ) {
    // VS_CONTROL_POINT_OUTPUT指定控制点的数据格式,INPUT_PATCH_SIZE指定每Patch所有的控制点个数(此为16)
    HS_OUTPUT Output;
    Output.vPosition = p[i].vPosition;
    return Output;
    }

    HS_CONSTANT_DATA_OUTPUT BezierConstantHS( InputPatch<VS_CONTROL_POINT_OUTPUT, INPUT_PATCH_SIZE> ip,
    uint PatchID : SV_PrimitiveID ) {
    HS_CONSTANT_DATA_OUTPUT Output;

    float TessAmount = g_fTessellationFactor;

    Output.Edges[0] = Output.Edges[1] = Output.Edges[2] = Output.Edges[3] = TessAmount;
    Output.Inside[0] = Output.Inside[1] = TessAmount;

    return Output;
    }

 

DomainShader:根据fixed function tessellator输出的UVW,以及hull shader输出的control points,最终生成顶点数据,输出到rasterization pipeline

  1. [domain("quad")]
    DS_OUTPUT BezierDS( HS_CONSTANT_DATA_OUTPUT input,
    float2 UV : SV_DomainLocation, // 从fixed function tessellator中得到
    const OutputPatch<HS_OUTPUT, OUTPUT_PATCH_SIZE> bezpatch ) { // 从hullShader中得到
    float4 BasisU = BernsteinBasis( UV.x );
    float4 BasisV = BernsteinBasis( UV.y );
    float4 dBasisU = dBernsteinBasis( UV.x );
    float4 dBasisV = dBernsteinBasis( UV.y );
    
    float3 WorldPos = EvaluateBezier( bezpatch, BasisU, BasisV );
    float3 Tangent = EvaluateBezier( bezpatch, dBasisU, BasisV );
    float3 BiTangent = EvaluateBezier( bezpatch, BasisU, dBasisV );
    float3 Norm = normalize( cross( Tangent, BiTangent ) );
    
    DS_OUTPUT Output;
    Output.vPosition = mul( float4(WorldPos,1), g_mViewProjection );
    Output.vWorldPos = WorldPos;
    Output.vNormal = Norm;
    
    return Output;
    }

DomainLocation具体含义:Defines the location on the hull of the current domain point being evaluated.

转载于:https://www.cnblogs.com/ActionFG/archive/2012/09/09/2677472.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值