Shader yang berbeda untuk objek yang berbeda DirectX 11

13

Saya sedang belajar Direct3D 11, dan dalam semua tutorial dasar yang saya temukan pada penulisan shader, Vertex dan Pixel shader ditulis sehingga mereka mengubah seluruh adegan dengan cara yang sama. Tutorial seperti render cube dengan tekstur ...

Tapi saya bertanya-tanya, bagaimana Anda membedakan objek? Bagaimana jika Anda ingin, misalnya, untuk mensimulasikan permukaan cermin pada beberapa objek dan menggunakan shader yang berbeda untuk membuat sisa adegan? Saya pikir sebagian besar game harus menggunakan banyak shader vertex dan pixel untuk mencapai berbagai tampilan dan transformasi.

Terima kasih.

jantobola
sumber

Jawaban:

23

Ya, mesin game pada umumnya akan memiliki beragam shader yang berbeda. Pola khasnya adalah:

  1. Saat menginisialisasi mesin dan memuat dunia game, siapkan semua shader yang akan Anda gunakan untuk rendering. Dengan "mempersiapkan" maksud saya memuatnya ke dalam memori, kompilasi jika perlu, dan lakukan semua ID3D11Device::CreatePixelShaderpanggilan serupa untuk mendapatkan objek shader D3D yang dialokasikan dan siap untuk digunakan. Simpan objek dalam array atau struktur data lainnya.

    Biasanya Anda akan memiliki hubungan satu-ke-satu antara vertex shaders dan pixel shaders yang dirancang untuk bekerja bersama. Saya menganggap mereka sebagai objek tunggal, yang saya sebut "shader", meskipun itu benar-benar berisi shader vertex dan pixel shader (dan mungkin juga geometri / lambung / domain shader juga).

  2. Setiap bingkai, setelah Anda menemukan daftar objek (jerat) untuk diurai, urutkan berdasarkan shader. Idenya adalah untuk meminimalkan berapa kali Anda mengganti shader dalam bingkai, dengan menggambar semua objek dengan shader yang diberikan bersamaan. Hal ini karena beralih shader adalah operasi yang agak mahal (meskipun Anda pasti bisa melakukannya beberapa ratus atau seribu kali per frame, sehingga tidak benar-benar yang mahal).

    Bahkan, Anda bisa melangkah lebih jauh dan mengurutkan jerat dengan shader pertama dan kedua materi. Yang dimaksud dengan "material", maksud saya adalah kombinasi shader dan satu set tekstur dan parameter untuk itu. Shader biasanya memiliki beberapa tekstur dan parameter numerik (disimpan dalam buffer konstan) yang dimasukkan ke dalamnya, jadi misalnya material batu bata dan material aspal mungkin menggunakan kode shader yang sama, hanya dengan tekstur yang berbeda.

  3. Untuk menggambar, cukup putar di atas shader, atur setiap shader di ID3D11DeviceContext, atur parameter apa saja (buffer konstan, tekstur, dll.), Lalu gambar objek. Dalam pseudocode, termasuk perbedaan shader / bahan yang saya sebutkan:

    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(...)

Ada banyak lagi yang bisa dikatakan tentang mengelola objek, jerat, shader, tata letak input, buffer konstan, dll. Tetapi ini sudah cukup untuk membantu Anda memulai. :)

Nathan Reed
sumber
Anda mengusulkan penyortiran berdasarkan shader dan kemudian oleh materi. Apakah Anda memiliki data keras tentang biaya beralih shader vs bahan beralih? Oh, dan untuk DX9, kombinasi VS / PS disebut "program". Saya tidak begitu yakin apakah mereka masih menggunakan terminologi itu di DX11.
Panda Pajama
1
@ PandaPajama Itu pertanyaan yang bagus. Tidak, saya tidak memiliki atau mengetahui pengukuran terkini tentang biaya aktual pengalihan material atau shader. Pendekatan ini telah menjadi "kebijaksanaan umum" selama bertahun-tahun, tetapi perlu melakukan beberapa pengukuran aktual untuk melihat bagaimana segala sesuatu telah berubah ... mungkin saya akan melakukan itu jika saya dapat menemukan waktu. :)
Nathan Reed