Różne shadery dla różnych obiektów DirectX 11

13

Uczę się Direct3D 11i we wszystkich podstawowych samouczkach dotyczących pisania programów do cieniowania zapisywane są programy do cieniowania wierzchołków i pikseli, aby w ten sam sposób przekształcać całą scenę. Samouczki, takie jak renderowanie kostki z teksturą ...

Ale zastanawiam się, jak odróżniasz przedmioty? Co jeśli na przykład chcesz symulować powierzchnię lustra na jakimś obiekcie i używać różnych shaderów do renderowania reszty sceny? Myślę, że większość gier musi korzystać z wielu programów cieniujących wierzchołki i piksele, aby uzyskać różnorodny wygląd i transformacje.

Dziękuję Ci.

jantobola
źródło

Odpowiedzi:

23

Tak, silnik gry będzie generalnie miał wiele różnych shaderów. Typowy wzór to:

  1. Podczas inicjowania silnika i ładowania świata gry przygotuj wszystkie shadery, których będziesz używać do renderowania. Przez „przygotowanie” mam na myśli załadowanie ich do pamięci, skompilowanie ich w razie potrzeby i wykonanie wszystkich ID3D11Device::CreatePixelShaderi podobnych wywołań w celu przydzielenia obiektów modułu cieniującego D3D i przygotowania ich do działania. Trzymaj obiekty w tablicy lub innej strukturze danych.

    Zwykle istnieje relacja jeden do jednego między modułami cieniującymi wierzchołki i modułami pikseli, które są zaprojektowane do współpracy. Myślę o nich jak o pojedynczym obiekcie, który nazywam po prostu „shaderem”, mimo że tak naprawdę zawiera shadery wierzchołków i shadery pikseli (a może także shadery geometrii / kadłuba / domeny).

  2. Każdą klatkę, po znalezieniu listy obiektów (siatek) do renderowania, posortuj je według modułu cieniującego. Chodzi o to, aby zminimalizować liczbę przełączeń modułów cieniujących w ramce, łącząc wszystkie obiekty za pomocą danego modułu cieniującego. To dlatego, że przełączanie shaderów jest nieco kosztowna operacja (choć z pewnością można zrobić to kilka setek lub tysięcy razy na ramie, więc to naprawdę nie jest to drogie).

    W rzeczywistości możesz pójść o krok dalej i sortować siatki według pierwszego modułu cieniującego, a drugiego materiału. Przez „materiał” rozumiem kombinację modułu cieniującego oraz zestawu tekstur i parametrów. Shadery zwykle mają pewne tekstury i parametry numeryczne (przechowywane w stałych buforach), które się do nich wprowadzają, więc na przykład materiał cegła i materiał asfaltowy mogą używać tego samego kodu modułu cieniującego, tylko z różnymi teksturami.

  3. Aby rysować, po prostu przesuń pętlę nad modułami cieniującymi, ustaw każdy moduł cieniujący w ID3D11DeviceContext, ustaw dowolne parametry (stałe bufory, tekstury itp.), A następnie narysuj obiekty. W pseudokodzie, w tym rozróżnieniu cieniowania / materiałów, wspomniałem:

    for each shader:
        // Set the device context to use this shader
        pContext->VSSetShader(shader.pVertexShader);
        pContext->PSSetShader(shader.pPixelShader);
    
        for each material that uses this shader:
            // Set the device context to use any constant buffers, textures, samplers,
            // etc. needed for this material
            pContext->VSSetConstantBuffers(...);
            pContext->PSSetConstantBuffers(...);
            pContext->PSSetShaderResources(...);
            pContext->PSSetSamplers(...);
    
            for each mesh that uses this material:
                // Set any constant buffers containing parameters specific to the mesh
                // (e.g. world matrix)
                pContext->VSSetConstantBuffers(...);
    
                // Set the context to use the vertex & index buffers for this mesh
                pContext->IASetInputLayout(mesh.pInputLayout);
                pContext->IASetVertexBuffers(...);
                pContext->IASetIndexBuffer(...);
                pContext->IASetPrimitiveTopology(...)
    
                // Draw it
                pContext->DrawIndexed(...)
    

O zarządzaniu obiektami, siatkami, modułami cieniującymi, układami wejściowymi, stałymi buforami itp. Można powiedzieć wiele więcej, ale to powinno wystarczyć, aby zacząć. :)

Nathan Reed
źródło
Proponujesz sortowanie według modułu cieniującego, a następnie według materiału. Czy masz jakieś twarde dane dotyczące kosztu zmiany shaderów w porównaniu do zmiany materiałów? Aha, a dla DX9 kombinacja VS / PS nazywa się „programem”. Nie jestem pewien, czy nadal używają tej terminologii w DX11.
Panda Pajama
1
@PandaPajama To dobre pytanie. Nie, nie mam ani nie znam żadnych ostatnich pomiarów rzeczywistego kosztu zmiany materiałów lub shaderów. Podejście to było „powszechną mądrością” od lat, ale warto dokonać rzeczywistych pomiarów, aby zobaczyć, jak się zmieniło ... może zrobię to, jeśli znajdę czas. :)
Nathan Reed