0

このような手法(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」署名を除いて、通常の頂点シェーダーのように見えます。ジオメトリシェーダーはどうですか?

4

1 に答える 1

2

このリンクはそれをかなりうまく説明していますが、基本的に要約します。

PreprocessedLoDVSとvs_4_0をプロファイルとして使用して、シェーダーをblobにコンパイルします

D3D11_SO_DECLARATION_ENTRYの配列であるStream出力レイアウトを作成します。これは、4つのコンポーネントでLODSセマンティックになります。

CreateGeometryShaderWithStreamOutを使用して頂点シェーダーを作成します

D3D11_BIND_STREAM_OUTPUTフラグを使用してバッファーを作成します(他のバッファーを作成する場合と同じように、バッファー入力としてバインドバックするためにSRVが必要になるため、そのサンプルからシェーダーリソースフラグも必要になります)。

このバッファをストリーム出力にバインドします(SOSetTargetsを使用)

Vertex Shaderをパイプラインに設定し、描画呼び出しを行います。

于 2013-01-20T12:17:22.903 に答える