2013-04-23 11 views
5

Mam renderer C++ DirectX 11, który pisałem.Używanie wielu buforów wierzchołków w DX10/DX11

Napisałem program ładujący COLLADA 1.4.1 do importowania danych COLLADA do użytku w obsłudze animacji szkieletowych.

Sprawdzam poprawność programu ładującego w tym momencie (i wspieram program COLLADA wcześniej w innym rendererze, który napisałem wcześniej przy użyciu innej technologii) i mam problem z dopasowaniem do COLLADA z DX10/11.

I 3 oddzielne bufory wierzchołek danych:

bufor wierzchołków unikalnych miejscach wierzchołków. Bufor wierzchołków Unique normals. Bufor wierzchołków o unikalnych współrzędnych tekstury.

tych wierzchołków bufory zawierają różną długość tablicy (pozycje elementów ma 2910, normalne jest więcej niż 9000, a współrzędne tekstury ma w przybliżeniu 3200)

COLLADA zawiera listę trójkąta daje mi indeksy do każdego z tych tablic dla danego trójkąta (na pierwszy rzut oka i na początku dziwnie, ale ostatecznie staje się to proste, gdy już z nim pracowałeś.)

Wiedząc, że DX10/11 obsługuje wiele buforów wierzchołków, uznałem, że będę wypełniał indeks DX10/11 bufor z indeksami do każdego z tych buforów * i * (to jest ważna część), te wskaźniki mogą być różne lub dany punkt w trójkącie.

Innymi słowy, można ustawić trzy bufory wierzchołków ustaw właściwy układ wejściowy, a następnie w buforze indeksu chciałbym umieścić równowartość:

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

Dokumentacja odnośnie korzystania z wielu buforów wierzchołków w Wygląda na to, że DirectX nie daje żadnych informacji o wpływie tego na bufor indeksu (więcej o tym później).

Uruchamianie kodu w ten sposób daje dziwne wyniki renderowania, w którym mogłem zobaczyć siatkę, którą rysowałem z przerwami poprawnie (dziwne wielokąty, ale około jedna trzecia punktów znajdowała się we właściwym miejscu - podpowiedź - podpowiedź)

Doszedłem do wniosku, że w tym momencie (w dniu wczorajszym) sknociłem dane lub indeksy, więc starannie sprawdziłem je wszystkie, więc pomyślałem, że wkręca się mój wkład lub coś innego. Wyeliminowałem to, używając wartości z buforów normalnych i teksturowych, aby alternatywnie ustawić wartość koloru używaną przez moduł cieniujący pikseli, kolory były poprawne, więc nie cierpiałem na problem z dopełnieniem.

Ostatecznie doszedłem do wniosku, że DX10/11 muszą być oczekiwać dane uporządkowane w inny sposób, więc próbowałem przechowywania indeksów w ten sposób:

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) 

Co dziwne, to dało świadczonych siatkę który wyglądał na 1/3 poprawnie - wskazówka - wskazówka.

Potem domyśliłem się, że być może DX10/DX11 chciał, aby indeksy były przechowywane "przez bufor wierzchołków", co oznacza, że ​​najpierw dodałbym wszystkie wskaźniki położenia dla wszystkich trójkątów, a następnie wszystkie normalne wskaźniki dla wszystkich trójkątów, a następnie całą teksturę skoordynować wskaźniki dla wszystkich trójkątów.

To przyniosło kolejną oczekującą poprawkę 1/3.

Pomogło mi to - no, na pewno DX10/11 nie zapewniłoby ci możliwości przesyłania strumieniowego z wielu buforów wierzchołków, a następnie oczekiwałoby tylko jednego indeksu na punkt trójkąta?

Tylko włączenie indeksów do bufora wierzchołków pozycji daje prawidłowo renderowaną siatkę, która niestety wykorzystuje nieprawidłowe wartości normalne i współrzędne tekstury.

Wygląda na to, że umieszczenie indeksów współrzędnych normalnych i teksturowych w buforze indeksu spowodowało błędne narysowanie prawidłowo renderowanej siatki.

Czy to oczekiwane zachowanie?

Wiele buforów wierzchołków - Jeden bufor indeksu i bufor indeksu mogą mieć tylko jeden indeks dla punktu trójkąta?

To naprawdę nie ma dla mnie sensu.

Pomoc!

+0

O mój Boże, nigdy nie wiedziałem, że możesz podzielić dane w ten sposób! – Lucius

+0

Miałem ten sam problem nie tak dawno temu i podczas szukania rozwiązania natrafiłem na [tę odpowiedź] (http://stackoverflow.com/a/2305383/1798046). To naprawdę pomogło mi uzyskać lepszy wgląd w problem. Mogę ci też pomóc. – Krienie

Odpowiedz

2

Pierwszą rzeczą, która przychodzi mi do głowy:

Cały sprzęt, który obsługuje shadery obliczeniowe (równowartość prawie wszystkich DirectX 10 i nowszych) obsługuje również ByteAddressBuffer s, a większość z nich obsługuje StructuredBuffer s. Możesz więc wiązać swoje tablice jako SRV s i mieć losowy dostęp do dowolnego z jego elementów w modułach cieniujących.

Coś takiego (nie testowane, tylko pseudokod):

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

Nazwijmy to "podejście obliczeniową cieniowania". Musisz korzystać z API DirectX 11.

Możesz również wiązać swoje indeksy w ten sam sposób i robić magię w shaderów. W takim przypadku musisz znaleźć aktualny identyfikator indeksu. Prawdopodobnie możesz wziąć to z SV_VertexId.

Prawdopodobnie można obejść te bufory i powiązać dane jakoś inaczej (próbkowanie tekstur kompatybilnych z DirectX 9! O_o).

Mam nadzieję, że pomoże!

+0

To interesujące rozwiązanie, muszę spróbować. Będę zainteresowany zobaczeniem aspektów wydajności związanych z ustawieniem tego na podstawie siatki. Dzięki – WTH

Powiązane problemy