dx10에서의 multi stream single index rendering & multi stream multi index rendering

반응형

Multi-Stream Single-Index Rendering in Direct3D 10

The setup is similar for performing multi-stream single-index rendering in Direct3D 10.
The same vertex buffers are created (position, normal, texture coordinates, alternate texture coordinates).
The sample then creates and input layout incorporating the separate vertex streams.
Again, the purpose is to make the multiple vertex streams look like one stream to the vertex shader.
Before rendering the sample must make sure that all streams are bound,
that the index buffer is bound, and that the correct input layout is set.
Notice that the third vertex stream ( stream number 2 ) can be switched between the original set of texture coordinates
and the alternate set of texture coordinates without affecting the other streams

    
    // Create a Input Layout for the MultiStream data.
    // Notice that the 4th parameter is the stream index.  This indicates the
    // VB that the particular data comes from.  In this case, position data
    // comes from stream 0.  Normal data comes from stream 1.  Texture coordinate
    // data comes from stream 2.
    const D3D10_INPUT_ELEMENT_DESC vertlayout_singleindex[] =
    {
        { "SV_POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "NORMAL",      0, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD0",   0, DXGI_FORMAT_R32G32_FLOAT,    2, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT iNumElements = sizeof(vertlayout_singleindex)/sizeof(D3D10_INPUT_ELEMENT_DESC);
    D3D10_PASS_DESC PassDesc;
    g_pRenderScene_SI->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    V_RETURN( pd3dDevice->CreateInputLayout( vertlayout_singleindex, iNumElements, PassDesc.pIAInputSignature, &g_pVertexLayout_SI ) );

Multi-Stream Multi-Index Rendering

The Direct3D 10 codepath also allows the use of vertex streams that are stored at different frequencies.
In order to access this vertex data stored at different frequencies, multiple index buffers are needed.
Note that there is no API to allow users of Direct3D 10 to set more than one index buffer at a time.
To perform this multi-stream multi-index rendering, some fancy shader work must be done.

First the buffers are created. In this scenario, 5 streams are created. They are described as follows:

FewVertexPositions: Stores NumVertices unique positions.
PositionIndices: Stores NumFaces*3 indices into the position buffer.
VertexTextureUV: Stores NumFaces*3 texture coordinates.
VertexTextureUV2: Stores NumFaces*3 texture coordinates.
FaceNormals: Stores NumFaces vertex normals.

V_RETURN( pd3dDevice->CreateBuffer( &bufferDesc, &vbInitData, &g_pVBs[ST_FEW_VERTEX_POSITION] ) );
V_RETURN( pd3dDevice->CreateBuffer( &bufferDesc, &vbInitData, &g_pVBs[ST_POSITION_INDEX] ) );
V_RETURN( pd3dDevice->CreateBuffer( &bufferDesc, &vbInitData, &g_pVBs[ST_VERTEX_TEXTUREUV] ) );
V_RETURN( pd3dDevice->CreateBuffer( &bufferDesc, &vbInitData, &g_pVBs[ST_VERTEX_TEXTUREUV2] ) );
V_RETURN( pd3dDevice->CreateBuffer( &bufferDesc, &vbInitData, &g_pVBs[ST_FACE_NORMAL] ) );

Note that FewVertexPosition holds NumVertices positions, while PositionIndices, VertexTextureUV, and VertexTextureUV2 hold NumFaces*3 values. In addition, FaceNormals only contains NumFaces values. This shows a large difference in data frequencies since NumVertices != NumFaces*3 in this scenario.


Since the position indices and texture coordinates share the same frequency, they can be added to the input layout. 

    // Create a Input Layout for the MultiStream MultiIndex data.
    //
    const D3D10_INPUT_ELEMENT_DESC vertlayout_multiindex[] =
    {
        { "POSINDEX",    0, DXGI_FORMAT_R32_UINT,   0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD0",   0, DXGI_FORMAT_R32G32_FLOAT,    1, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
    };
    iNumElements = sizeof(vertlayout_multiindex)/sizeof(D3D10_INPUT_ELEMENT_DESC);
    g_pRenderScene_MI->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    V_RETURN( pd3dDevice->CreateInputLayout( vertlayout_multiindex, iNumElements, PassDesc.pIAInputSignature, &g_pVertexLayout_MI ) );
  

They are also bound as vertex buffers similarly to the way it is handled for multi-stream single-index rendering. 

        pd3dDevice->IASetInputLayout( g_pVertexLayout_MI );

        pBuffers[0] = g_pVBs[ST_POSITION_INDEX];
        if( g_bUseAltUV )
            pBuffers[1] = g_pVBs[ST_VERTEX_TEXTUREUV2];
        else
            pBuffers[1] = g_pVBs[ST_VERTEX_TEXTUREUV];

        strides[0] = sizeof(UINT);
        strides[1] = sizeof(D3DXVECTOR2);

However, the data stored at different frequencies must be passed in as buffers. 

        g_pPosBuffer->SetResource( g_pFewVertexPosRV );
        g_pNormBuffer->SetResource( g_pFaceNormalRV );

The reset of the magic happens in the vertex shader. The vertex position is loaded from the position buffer based upon the input position index. The face normal is loaded from the normal buffer using the vertexID/3. SV_VertexID is automatically generated by the input assembler.

float4 Pos = g_posBuffer.Load( input.PositionIndex );   
float4 Norm = g_normBuffer.Load( input.vertID/3 );

멀티스트림은 갈아끼울때 편하다.
일단 넘겨줄때도 필요한거만 부분으로 해서 넘겨줄수 있으니까 좋고.

멀티인덱스는 dx10으로 넘어오면서 지원되는 것 같은데
말 그대로 인덱스 버퍼를 여러개 사용하겠다는 거지..
이건 뭐 LOD처럼 쓰면 되는건가??
오브젝트 상세히 그리는 거나 줌아웃 땡길때 여러녀석들은 최적화한 정점 인덱스로 찍어주는데 활용할 수 있겠다.

멀티 스트림 :
http://www.gpgstudy.com/forum/viewtopic.php?p=97359
http://blog.paran.com/pgpz/17841659

'Study > Directx 10' 카테고리의 다른 글

dx10 파이프라인.  (0) 2010.07.08
Resource (자원)  (0) 2010.07.03
듀얼모니터.. 빌어먹을 dxut  (0) 2010.06.13
IDXGIFactory::MakeWindowAssociation Method (Windows)  (0) 2010.06.05
반사  (0) 2010.06.04
TAGS.

Comments