Menggunakan beberapa shader


53

Saya saat ini sedang mempelajari shading opengl tetapi saya tidak dapat menemukan sesuatu: bagaimana menerapkan shader yang berbeda pada objek, misalnya, teko yang dibuat menggunakan toon shader dan yang lain dalam adegan yang sama menggunakan permukaan yang sangat reflektif dan yang lainnya terdistorsi dari fungsi noise, seperti di video ini

http://www.youtube.com/watch?v=1ogg4ZfdBqU

Yang lain menerapkan bloom shader dalam sebuah adegan dan gerakan mengaburkan shader sesudahnya. Bagaimana cara mencapai efek tersebut ketika Anda hanya dapat memiliki satu vertex shader dan satu fragmen shader? Apakah ada trik seperti menggunakan lebih dari satu program shader?


Jawaban baik Nathan dan David, inilah mengapa Anda melihat istilah render pass atau shader pass ; diperlukan beberapa lintasan untuk menyusun gambar / bingkai akhir. Salah satu alasan mengapa pemrosesan GPU menjadi paralel sangat terkutuk dan dengan demikian begitu cepat adalah kebutuhan untuk beberapa lintasan per frame. Kembali ke penyaji peranti lunak Quake II atau Half Life untuk mengingatkan diri Anda betapa banyak cinta melewati shader menambah pengalaman grafis 3D keseluruhan.
Insinyur

Jawaban:


59

Jawaban sederhananya adalah Anda mengubahnya di antara setiap panggilan draw. Mengatur shader, menggambar teko, mengatur shader lain, menggambar teko lain.

Untuk hal-hal yang lebih kompleks di mana Anda perlu menerapkan beberapa shader hanya pada satu objek seperti blur, cahaya dan sebagainya. Anda pada dasarnya memiliki semua yang dirender menjadi tekstur. Lalu Anda membuat quad di seluruh layar Anda dengan tekstur yang diterapkan saat menggunakan shader lain.

Misalnya jika Anda ingin memberikan efek cahaya, pertama-tama Anda harus membuat adegan non-glowing biasa, lalu render hanya siluet berwarna dari hal-hal yang ingin Anda pijar pada tekstur kemudian Anda beralih ke shader blur dan membuat Anda quad dengan tekstur yang melekat pada adegan non-glowing Anda.

Ada teknik lain yang disebut Deferred shading di mana Anda membuat adegan tanpa pencahayaan dan menerapkannya nanti di ruang layar. Tujuan utamanya adalah untuk mengurangi biaya pencahayaan per piksel.

Biasanya Anda membuat buffer warna yang diletakkan di layar. Dengan shading yang ditangguhkan, Anda alih-alih membuat buffer warna serta buffer normal dan kedalaman dalam satu lintasan shader (Anda dapat menyimpan vektor normal dan kedalaman dalam tekstur seperti dengan pemetaan normal dan tinggi).

Ini berarti, untuk setiap piksel, Anda tahu posisi potongan terdekat dari geometri non-transparan (kedalaman atau jarak dari mata) warna dan normal. Karena itu, Anda dapat menerapkan pencahayaan ke setiap piksel di layar alih-alih ke setiap piksel yang terlihat dari setiap objek yang Anda render. Ingat bahwa beberapa objek akan digambar di atas objek lain jika adegan tidak sempurna ditampilkan di depan ke belakang.

Untuk bayangan Anda benar-benar membuat buffer kedalaman dari sudut pandang cahaya Anda kemudian gunakan informasi kedalaman itu untuk mengetahui di mana cahaya menyerang. Itu disebut pemetaan bayangan (ada juga pendekatan lain yang disebut volume bayangan yang berhasil membentuk siluet geometri dan mengekstruksinya, tetapi Anda masih akan menggunakan shader.).

Dengan OpenGL yang lebih modern (3.0+) Anda menggunakan Objek Framebuffer dengan Objek Renderbuffers terlampir. Karena renderbuffers dapat diperlakukan seperti tekstur. Anda mungkin melakukan hal-hal seperti memiliki 1 shader render ke beberapa renderbuffers yang berbeda (jadi Anda tidak harus membuat tekstur Anda maka normals Anda kemudian komponen cahaya) tetapi praktik dasarnya masih sama.

Juga diinginkan untuk meminimalkan jumlah sakelar shader sebanyak mungkin untuk menghemat overhead. Jadi beberapa mesin akan mengelompokkan semuanya dengan bahan yang sama sehingga semuanya dapat ditarik sekaligus.


16

Anda hanya mengikat satu shader, membuat semua objek menggunakan shader itu, lalu mengikat shader berikutnya, membuat objek menggunakan yang shader itu, dll.

Anda dapat memiliki banyak objek shader (shader dimuat ke dalam memori dan dikompilasi) seperti yang Anda inginkan; hanya satu yang dapat diikat (aktif) dalam satu waktu.


5
Dalam hal implementasi, di setiap frame saya menggunakan glUseProgram (1) dan glUseProgram (2) untuk mengubah shader? Seberapa mahalnya kinerja itu?
ibrabeicker

4
Ini adalah biaya nontrivial (meskipun lebih sedikit pada GPU terbaru daripada yang sebelumnya). Itulah sebabnya kebanyakan orang menyortir objek mereka berdasarkan materi, menyatukan semua objek dengan material yang sama. Tetapi Anda tentu mampu mengubah program puluhan hingga ratusan kali per frame, jika tidak lebih.
Nathan Reed

9

Menggunakan lebih dari satu shader dalam sebuah adegan cukup sederhana; ubah shader, atur nilai untuknya, lalu render objek.

Hati-hati, bagaimanapun, mengganti shader bisa jadi mahal, jadi penggantian shader harus dijaga agar tetap minimum. Ada beberapa cara untuk mengurangi dampak ini sambil mendapatkan semua efek yang Anda inginkan.

Metode pertama, dan biasanya yang paling diinginkan, adalah menambahkan fungsionalitas untuk semua teknik shader Anda menjadi satu shader dan menggunakan kondisi yang Anda atur untuk membuat setiap objek dengan cara yang berbeda dengan shader yang sama. Saya tidak tahu tentang shader OpenGL dan GLSL tetapi dengan shader HLSL dan DirectX ini dapat dikelompokkan bersama sebagai "teknik" dan Anda dapat mengatur teknik alih-alih mengubah shader. Ini memungkinkan Anda untuk benar-benar memiliki beberapa pixel dan vertex shader yang berbeda dalam file yang sama.

Cara kedua untuk mengurangi dampak kinerja adalah mengatur shader, membuat setiap objek yang menggunakan shader itu, lalu ulangi. Dengan kata lain, kumpulan rendering Anda.

Jika Anda ingin menerapkan dua efek yang berbeda pada objek yang sama (yaitu menerapkan katakanlah shader toon maka beberapa pencahayaan) Anda dapat melakukannya dengan dua cara yang berbeda. Yang pertama adalah menulis shader yang menerapkan banyak efek dalam fungsi yang sama. Cara kedua adalah membuat model sekali dengan masing-masing shader dan mencampur hasilnya dengan mengatur opsi campuran yang berbeda. Namun, ini lebih banyak pekerjaan, dan tidak dapat dicapai dalam semua keadaan. Karena itu pilihan terbaik adalah menggabungkan semua efek Anda menjadi satu shader.


7

Cara lain untuk melakukan yang telah saya temukan adalah melalui sesuatu yang disebut glsl subroutines, di mana setiap jenis shader didefinisikan dalam satu fungsi, dan dalam aplikasi OpenGL, kita dapat mendefinisikan subrutin saat ini, menggambar titik penyangga, mengubah subrutin dan render buffer lain


4
Ini membutuhkan perangkat keras berkemampuan GL 4.x, yang merupakan perangkat keras kelas DX11.
Nicol Bolas
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.