0

How do I convert such technique (from nVidia InstancedTesselation sample) to plain HLSL + DirectX 11 C++ code?

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 looks like usual vertex shader, except "LODS" signature, and what about geometry shader?

4

1 回答 1

2

这个链接很好地解释了它,但基本上是为了总结。

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

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

使用CreateGeometryShaderWithStreamOut创建顶点着色器

创建一个带有 D3D11_BIND_STREAM_OUTPUT 标志的缓冲区(与创建任何其他缓冲区一样,从该样本中您还需要着色器资源标志,因为您需要 SRV 绑定回作为缓冲区输入)。

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

将您的顶点着色器设置为管道并进行绘图调用。

于 2013-01-20T12:17:22.903 回答