效果框架“ConstructGSWithSO”到普通的HLSL和C ++

时间:2013-01-20 10:40:32

标签: directx hlsl

如何将此类技术(从nVidia InstancedTesselation示例)转换为纯HLSL + DirectX 11 C ++代码?

float4 PreprocessedLoDVS( uint id : SV_InstanceID, uniform int method) : LODS
{
    float4 tessLevel;
    if (method == 1)    //Gregory
    {
        float3 positionControlPoints[20];
        //  8     9     10     11
        // 12   0\1     2/3    13
        // 14   4/5     6\7    15
        // 16    17     18     19
        LoadGregoryPositionControlPoints(id, positionControlPoints);
        tessLevel.x = evaluateEdgeLoD(positionControlPoints[16], positionControlPoints[14], positionControlPoints[12], positionControlPoints[8]);
        tessLevel.y = evaluateEdgeLoD(positionControlPoints[19], positionControlPoints[15], positionControlPoints[13], positionControlPoints[11]);
        tessLevel.z = evaluateEdgeLoD(positionControlPoints[16], positionControlPoints[17], positionControlPoints[18], positionControlPoints[19]);
        tessLevel.w = evaluateEdgeLoD(positionControlPoints[8], positionControlPoints[9], positionControlPoints[10], positionControlPoints[11]);
    }
    else if (method == 0) {  //Regular
        float3 positionControlPoints[16];
        //  0     1     2     3
        //  4     5     6     7    
        //  8     9     10    11
        //  12    13    14    15
        LoadRegularControlPoints(id, positionControlPoints);
        tessLevel.x = evaluateEdgeLoD(positionControlPoints[ 0], positionControlPoints[ 4], positionControlPoints[ 8], positionControlPoints[12]);
        tessLevel.y = evaluateEdgeLoD(positionControlPoints[ 3], positionControlPoints[ 7], positionControlPoints[11], positionControlPoints[15]);
        tessLevel.w = evaluateEdgeLoD(positionControlPoints[ 0], positionControlPoints[ 1], positionControlPoints[ 2], positionControlPoints[ 3]);
        tessLevel.z = evaluateEdgeLoD(positionControlPoints[12], positionControlPoints[13], positionControlPoints[14], positionControlPoints[15]);
    }
    else if (method == 2) {  //Bezier
        float3 positionControlPoints[16];
        //  0     1     2     3
        //  4     5     6     7    
        //  8     9     10    11
        //  12    13    14    15
        LoadBezierPositionControlPoints(id, positionControlPoints);
        tessLevel.x = evaluateEdgeLoD(positionControlPoints[ 0], positionControlPoints[ 4], positionControlPoints[ 8], positionControlPoints[12]);
        tessLevel.y = evaluateEdgeLoD(positionControlPoints[ 3], positionControlPoints[ 7], positionControlPoints[11], positionControlPoints[15]);
        tessLevel.z = evaluateEdgeLoD(positionControlPoints[12], positionControlPoints[13], positionControlPoints[14], positionControlPoints[15]);
        tessLevel.w = evaluateEdgeLoD(positionControlPoints[ 0], positionControlPoints[ 1], positionControlPoints[ 2], positionControlPoints[ 3]);
    }
    else if (method == 3) {  //Pm
        //          18  14  13   12                             
        //          19           8         
        //          20           7              
        //          0   1   2    6                 
        float3 positionControlPoints[24];
        LoadPmControlPoints(id, positionControlPoints);
        tessLevel.x = evaluateEdgeLoD(positionControlPoints[ 0], positionControlPoints[20], positionControlPoints[19], positionControlPoints[18]);
        tessLevel.y = evaluateEdgeLoD(positionControlPoints[ 6], positionControlPoints[ 7], positionControlPoints[ 8], positionControlPoints[12]);
        tessLevel.z = evaluateEdgeLoD(positionControlPoints[18], positionControlPoints[14], positionControlPoints[13], positionControlPoints[12]);
        tessLevel.w = evaluateEdgeLoD(positionControlPoints[ 0], positionControlPoints[ 1], positionControlPoints[ 2], positionControlPoints[ 6]);
    }
    else {
        tessLevel=float4(2,2,2,2);
    }
    return tessLevel;
}

technique10 LoDRegularTechnique
{
    pass P0
    {
        SetDepthStencilState( DisableDepthWrites, 0 );

        SetVertexShader( CompileShader( vs_4_0, PreprocessedLoDVS(0) ) );
        SetGeometryShader( ConstructGSWithSO( CompileShader( vs_4_0, PreprocessedLoDVS(0) ), "LODS.xyzw" ) );
        SetPixelShader( NULL );
    }
}

PreprocessedLoDVS看起来像通常的顶点着色器,除了“LODS”签名,几何着色器怎么样?

1 个答案:

答案 0 :(得分:2)

这个link很好地解释了它,但基本上总结一下。

使用PreprocessedLoDVS和vs_4_0作为配置文件将着色器编译为blob

创建一个Stream输出布局,这是一个D3D11_SO_DECLARATION_ENTRY数组,它将是4个组件的LODS语义。

使用CreateGeometryShaderWithStreamOut

创建顶点着色器

使用D3D11_BIND_STREAM_OUTPUT标志创建一个缓冲区(与创建任何其他缓冲区相同,从该样本开始,您还需要着色器资源标记,因为您需要SRV作为缓冲区输入进行绑定)。

将此缓冲区绑定到流输出(使用SOSetTargets

将Vertex Shader设置为管道并进行绘制调用。