2013-04-23 11 views
5

Ho un renderer C++ DirectX 11 che ho scritto.Utilizzo di più buffer di vertici in DX10/DX11

Ho scritto un caricatore COLLADA 1.4.1 per importare i dati COLLADA da utilizzare nel supporto delle animazioni scheletriche.

Sto convalidando il caricatore a questo punto (e ho già supportato COLLADA in un altro renderer che ho scritto in precedenza usando una tecnologia diversa) e sto incontrando un problema che combina COLLADA con DX10/11.

Ho 3 buffer di vertici separati di dati:

Un vertex buffer di vertici posizioni uniche. Un buffer di vertici delle normali Uniche. Un buffer di vertici di coordinate di texture uniche.

Questi buffer di vertici contengono diversa lunghezza dell'array (posizioni comprende 2910 elementi, normali ha più di 9000, e coordinate texture ha circa 3200.)

COLLADA fornisce un elenco triangolo che mi dà gli indici in ciascuna di queste matrici per un dato triangolo (verbose e stranamente fatte all'inizio, ma alla fine diventa semplice una volta che hai lavorato con esso.)

Sapendo che DX10/11 supporta più vertex buffer ho pensato che avrei riempito l'indice DX10/11 buffer con indici in ciascuno di questi buffer * e * (questa è la parte importante), questi indici potrebbero essere diversi f o un dato punto di un triangolo.

In altre parole, ho potuto impostare i tre buffer di vertici, impostare il layout ingresso corretto, e quindi nel buffer dell'indice metterei l'equivalente di:

l_aIndexBuffer[ NumberOfTriangles * 3 ] 

for(i = 0; i < NumberOfTriangles; i++) 
{ 
    l_aIndexBufferData.add(triangle[i].Point1.PositionIndex) 
    l_aIndexBufferData.add(triangle[i].Point1.NormalIndex) 
    l_aIndexBufferData.add(triangle[i].Point1.TextureCoordinateIndex) 
} 

La documentazione relativa utilizzando più buffer di vertici in DirectX non sembra dare alcuna informazione su come questo influisce sul buffer dell'indice (ne parleremo più avanti)

Eseguendo il codice in questo modo si ottengono risultati di rendering strani dove potrei vedere la mesh che avevo disegnato in modo intermittente correttamente (strano poligoni ma circa un terzo dei punti erano nel posto giusto - suggerimento - suggerimento)

Ho immaginato di aver rovinato i miei dati oi miei indici a questo punto (ieri), quindi ho accuratamente convalidato tutto, e così ho pensato di incasinare il mio input o qualcos'altro. L'ho eliminato utilizzando i valori dei buffer di texture e normali per impostare in alternativa il valore del colore utilizzato dal pixel shader, i colori erano corretti quindi non stavo soffrendo di problemi di padding.

definitiva sono giunto alla conclusione che DX10/11 deve essere sorprese i dati ordinati in modo diverso, così ho provato memorizzare gli indici in questo modo:

indices.add(Point1Position index) 
indices.add(Point2Position index) 
indices.add(Point3Position index) 
indices.add(Point1Normal index) 
indices.add(Point2Normal index) 
indices.add(Point3Normal index) 
indices.add(Point1TexCoord index) 
indices.add(Point2TexCoord index) 
indices.add(Point3TexCoord index) 

Stranamente, questo prodotto a maglie resi quello sembrava 1/3 corretto - suggerimento - suggerimento.

Ho quindi ipotizzato che forse DX10/DX11 volesse che gli indici fossero archiviati "da vertex buffer", ovvero che avrei aggiunto tutti gli indici di posizione per tutti i triangoli, quindi tutti gli indici normali per tutti i triangoli, quindi tutta la trama coordinare gli indici per tutti i triangoli.

Questo ha restituito un'altra mesh 1/3 corretta.

Questo mi ha fatto pensare - beh, sicuramente DX10/11 non ti fornirebbe la possibilità di eseguire lo streaming da più buffer di vertice e quindi di prevedere solo un indice per punto del triangolo?

Solo gli indici nel buffer dei vertici delle posizioni restituiscono una mesh correttamente renderizzata che purtroppo utilizza le normali e le coordinate di trama errate.

Sembra che inserire gli indici di coordinate normali e di trama nel buffer dell'indice abbia causato un disegno errato sulla mesh correttamente sottoposta a rendering.

È questo il comportamento previsto?

Buffer di vertici multipli: un buffer di indice e il buffer di indice possono avere un solo indice per un punto di un triangolo?

Questo davvero non ha senso per me.

Help!

+0

Oh mio Dio, non ho mai saputo che potresti dividere i tuoi dati di vertice in questo modo! – Lucius

+0

Ho avuto lo stesso problema non molto tempo fa e durante la ricerca di una soluzione mi sono imbattuto in [questa risposta] (http://stackoverflow.com/a/2305383/1798046). Mi ha davvero aiutato a capire meglio il problema. Potrei aiutarti anche tu. – Krienie

risposta

2

La prima cosa che mi viene in mente:

Tutto l'hardware che supporta shader calcolo (pari a quasi tutte le DirectX 10 e successive) supporta anche ByteAddressBuffer s e la maggior parte di esso supporta StructuredBuffer s. Quindi puoi associare i tuoi array come SRV s e avere accesso casuale a uno qualsiasi dei suoi elementi in shader.

qualcosa di simile (non testato, solo pseudocodice):

// Indices passed as vertex buffer to shader 
// Think of them as of "references" to real data 
struct VS_INPUT 
{ 
    uint posidx; 
    uint noridx; 
    uint texidx; 
} 

// The real vertex data 
// You pass it as structured buffers (similar to textures) 
StructuredBuffer<float3> pos : register (t0); 
StructuredBuffer<float3> nor : register (t1); 
StructuredBuffer<float2> tex : register (t2); 


VS_OUTPUT main(VS_INPUT indices) 
{ 
    // in shader you read data for current vertex 
    float3 pos = pos[indices.posidx]; 
    float3 nor = nor[indices.noridx]; 
    float2 tex = tex[indices.texidx]; 

    // here you do something 
} 

Chiamiamolo che "l'approccio dello shader di calcolo". È necessario utilizzare l'API di DirectX 11.

Inoltre puoi legare i tuoi indici nello stesso modo e fare un po 'di magia negli shader. In questo caso è necessario trovare l'ID dell'indice corrente. Probabilmente puoi prenderlo da SV_VertexId.

E probabilmente è possibile aggirare questi buffer e collegare i dati in qualche modo (campionamento di trama compatibile con DirectX 9! O_o).

Spero che aiuti!

+0

Questa è una soluzione interessante, dovrò fare una prova. Sarò interessato a vedere gli aspetti relativi alle prestazioni nell'impostazione di questo per mesh. Grazie – WTH

Problemi correlati