2013-04-23 5 views
5

Ich habe einen C++ DirectX 11-Renderer, den ich geschrieben habe.Verwenden mehrerer Vertex-Puffer In DX10/DX11

Ich habe einen COLLADA 1.4.1 Loader geschrieben, um COLLADA Daten für die Unterstützung von Skelettanimationen zu importieren.

Ich validiere den Loader zu diesem Zeitpunkt (und ich habe COLLADA vorher in einem anderen Renderer unterstützt, den ich vorher mit einer anderen Technologie geschrieben habe) und ich stoße auf ein Problem mit COLLADA mit DX10/11.

Ich habe 3 separaten Scheitel Datenpuffer:

einen Scheitel Puffer von Unique Eckpunktpositionen. Ein Vertex-Puffer von Unique-Normalen. Ein Eckenpuffer von Unique texture coordinates.

Diese Vertexpuffer verschiedenen Arraylänge enthalten (Positionen 2910 Elemente aufweist, hat Normalen mehr als 9000, und Texturkoordinaten hat etwa 3200.)

COLLADA stellt eine Dreiecksliste, die mich um die Indizes in jedem dieser Arrays gibt Für ein gegebenes Dreieck (zuerst ausführlich und seltsam, aber letztendlich wird es einfach, wenn Sie damit gearbeitet haben).

Da ich wusste, dass DX10/11 mehrere Vertexpuffer unterstützt, dachte ich, dass ich den DX10/11 Index füllen würde Puffer mit Indizes in jeden dieser Puffer * und * (dies ist der wichtige Teil), diese Indizes könnten anders sein f oder ein bestimmter Punkt eines Dreiecks.

Mit anderen Worten kann ich den drei Vertex-Puffer eingestellt, stellen Sie das richtige Eingabelayout und dann in dem Indexpuffer würde ich das äquivalent setzen:

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) 
} 

Die Dokumentation mehr Vertex-Puffers bezüglich der Verwendung von in DirectX scheint keine Informationen darüber zu geben, wie sich dies auf den Indexpuffer auswirkt (mehr dazu später).

Das Ausführen des Codes auf diesem Weg führt zu seltsamen Renderergebnissen, bei denen ich das Netz, das ich intermittierend gezeichnet habe, sehen konnte (seltsam Polygone aber etwa ein Drittel der Punkte waren an der richtigen Stelle - Hinweis - Hinweis)

Ich dachte, ich hätte meine Daten oder meine Indizes zu diesem Zeitpunkt (gestern) vermasselt, also habe ich alles sorgfältig überprüft, und so dachte ich mir, dass ich meinen Input oder etwas anderes anschraubte. Ich eliminierte dies, indem ich die Werte aus den normalen und Textur-Puffern verwendete, um alternativ den vom Pixel-Shader verwendeten Farbwert einzustellen, die Farben waren korrekt, so dass ich kein Polsterungsproblem hatte.

Schließlich kam ich zu dem Schluss, dass DX10/11 die Daten in einer anderen Art und Weise geordnet erwarten sein muss, so habe ich versucht, die Indizes in dieser Weise zu speichern:

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) 

Merkwürdigerweise dieses ein gerendertes mesh ergab das sah 1/3 korrekt aus - Hinweis - Hinweis.

Ich vermutete dann, dass DX10/DX11 vielleicht wollte, dass die Indizes 'nach Vertexpuffer' gespeichert werden, was bedeutet, dass ich zuerst alle Positionsindizes für alle Dreiecke, dann alle normalen Indizes für alle Dreiecke und dann die gesamte Textur addiere Koordinatenindizes für alle Dreiecke.

Dies ergab ein weiteres 1/3 richtiges (aussehendes) Netz.

Das hat mich zum Nachdenken gebracht - nun, DX10/11 würde Ihnen nicht die Möglichkeit geben, aus mehreren Vertex-Puffern zu streamen und dann tatsächlich nur einen Index pro Dreieck zu erwarten?

Nur die Einbeziehung von Indizes in den Vertex-Puffer von Positionen führt zu einem korrekt gerenderten Netz, das leider die falschen Normalen und Texturkoordinaten verwendet.

Es scheint, dass das Einfügen der normalen und Texturkoordinatenindizes in den Indexpuffer ein fehlerhaftes Zeichnen über das ordnungsgemäß gerenderte Netz verursacht hat.

Ist dies das erwartete Verhalten?

Mehrere Scheitelpunktpuffer - Ein Indexpuffer und der Indexpuffer können nur einen einzigen Index für einen Punkt eines Dreiecks haben?

Das macht wirklich keinen Sinn für mich.

Hilfe!

+0

Oh mein Gott, ich wusste nie, dass du deine Eckendaten auf diese Weise teilen kannst! – Lucius

+0

Ich hatte das gleiche Problem vor nicht allzu langer Zeit und bei der Suche nach einer Lösung stieß ich auf [diese Antwort] (http://Stackoverflow.com/a/2305383/1798046). Es hat mir wirklich geholfen, mehr Einblick in das Problem zu bekommen. Ich könnte dir auch helfen. – Krienie

Antwort

2

Die erste Sache, die in meinem Kopf kommt:

Alle Hardware, die ByteAddressBuffer s unterstützt auch unterstützt Compute Shaders (gleich fast alle DirectX 10 und höher) und das meiste davon unterstützt StructuredBuffer s. So können Sie Ihre Arrays als SRV s binden und haben zufälligen Zugriff auf eines seiner Elemente in Shadern.

Etwas Ähnliches (nicht getestet, nur Pseudo-Code):

// 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 
} 

ist, dass "Compute-Shader-Ansatz" Let nennen. Sie müssen die DirectX 11-API verwenden.

Sie können auch Ihre Indizes in der gleichen Weise binden und einige Magie in Shadern machen. In diesem Fall müssen Sie die aktuelle Index-ID herausfinden. Wahrscheinlich können Sie es von SV_VertexId nehmen.

Und wahrscheinlich können Sie diese Puffer umgehen und irgendwie Daten binden (DirectX 9 kompatible Textur Sampling! O_o).

Hoffe es hilft!

+0

Das ist ein interessanter Workaround, ich muss es versuchen. Ich bin daran interessiert, die Leistungsaspekte der Einstellung auf einer Pro-Mesh-Basis zu sehen. Vielen Dank – WTH

Verwandte Themen