0

複数のマテリアルを持つメッシュを処理できる柔軟な Geometry Instancing コードを作成しようとしています。1 つのマテリアルのメッシュの場合、すべて問題ありません。1 回の描画呼び出しで、必要な数のインスタンスをレンダリングすることができます。

複数のマテリアルを使用すると、状況が少し複雑になります。私のメッシュは .x ファイルから来ています。1 つの頂点バッファーと 1 つのインデックス バッファーがありますが、いくつかのマテリアルがあります。各サブセット (マテリアル) に対してレンダリングするインデックスは、属性配列に格納されます。

私が使用するコードは次のとおりです。

d3ddev->SetVertexDeclaration( m_vertexDeclaration );    
d3ddev->SetIndices( m_indexBuffer );

d3ddev->SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INDEXEDDATA | m_numInstancesToDraw ));
d3ddev->SetStreamSource(0, m_vertexBuffer, 0, D3DXGetDeclVertexSize( m_geometryElements, 0 ) );

d3ddev->SetStreamSourceFreq(1, (D3DSTREAMSOURCE_INSTANCEDATA | 1ul));
d3ddev->SetStreamSource(1, m_instanceBuffer, 0, D3DXGetDeclVertexSize( m_instanceElements, 1 ) );

m_effect->Begin(NULL, NULL);    // begin using the effect
m_effect->BeginPass(0);         // begin the pass

for( DWORD i = 0; i < m_numMaterials; ++i ) // loop through each subset.
{
    d3ddev->SetMaterial(&m_materials[i]);    // set the material for the subset
    if(m_textures[i] != NULL)
    {
       d3ddev->SetTexture( 0, m_textures[i] );
    }

    d3ddev->DrawIndexedPrimitive( 
        D3DPT_TRIANGLELIST,             // Type
        0,                              // BaseVertexIndex
        m_attributes[i].VertexStart,    // MinIndex
        m_attributes[i].VertexCount,    // NumVertices
        m_attributes[i].FaceStart * 3,  // StartIndex
        m_attributes[i].FaceCount       // PrimitiveCount
    );
}  

m_effect->EndPass();
m_effect->End();

d3ddev->SetStreamSourceFreq(0,1);
d3ddev->SetStreamSourceFreq(1,1);

このコードは、最初のマテリアルに対してのみ機能します。2 番目のマテリアルでループを開始すると、レンダリングされないため、最初のマテリアルはインデックス 0 のものを意味します。しかし、PIX で頂点バッファをデバッグすると、すべてのマテリアルが適切に処理されていることがわかります。そのため、頂点シェーダーの後に何かが起こります。

もう 1 つの奇妙な問題です。インスタンス データを含むストリーム ソースを頂点サイズ 0 に設定すると、すべてのマテリアルがレンダリングされます。

だからこれの代わりに:

d3ddev->SetStreamSource(1, m_instanceBuffer, 0, D3DXGetDeclVertexSize( m_instanceElements, 1 ) );

私はそれを次のように置き換えます:

d3ddev->SetStreamSource(1, m_instanceBuffer, 0, 0 );

しかしもちろん、このコードでは、同じインスタンス データを何度も再利用するため、すべてのインスタンスが同じ位置にレンダリングされます。

最後に、D3DCREATE_SOFTWARE_VERTEXPROCESSING でデバイスを作成すると、すべて正常に動作します。ハードウェアのみに問題がありますが、残念ながら DirectX はデバッグ モードで問題を報告しません。

4

2 に答える 2

0

私は同じ問題を抱えていましたが、私の場合、問題はメッシュをインスタンス化するためのプールにありました。このメッシュはもともと SYSTEM_MEMORY にありましたが、インスタンス化されたメッシュは POOL_DEFAULT にありました。インスタンス化メッシュをデフォルトのメモリに配置するように変更すると、すべてが希望どおりに機能しました。

それが役に立てば幸い。

于 2014-09-17T15:39:56.580 に答える
0

Shader Model 3のドキュメントを参照してください。

ハードウェアにシェーダーを実装する場合、他のシェーダー バージョンで vs_3_0 または ps_3_0 を使用することはできません。また、固定関数パイプラインでいずれのシェーダー タイプも使用することはできません。これらの変更により、ドライバーとランタイムを簡素化できます。唯一の例外は、ソフトウェアのみの vs_3_0 シェーダーがどのピクセル シェーダー バージョンでも使用できることです。

于 2013-02-10T00:40:40.860 に答える