Apakah rendering / arsir ditangguhkan dimungkinkan dengan OpenGL ES 2.0?

20

Saya menanyakan ini di StackOverflow , tetapi mungkin lebih masuk akal di sini:

Adakah yang menerapkan rendering / penangguhan yang ditangguhkan di bawah OpenGL ES 2.0? Itu tidak mendukung MRT, jadi hanya dengan satu penyangga warna, itu bukan sesuatu yang dapat diimplementasikan dengan cara "biasa".

Secara khusus, saya menjelajahi iPad, iPhone4 (iPhone 3gs), dan Android. Pada aplikasi GLESView di iPad / iPhone4 / iPhone3gs, ekstensi GL_OES_RGB8_RGBA8 hadir, dan saya belum melihat terlalu dalam, tetapi dengan 8bits / saluran, ide ini menarik: http://www.gamedev.net/topic/ 562138-opengl-es-20-and-ditangguhkan-shading /

Ada ide lain? Apakah itu layak dilakukan, berdasarkan kinerja?

Jim Buck
sumber
Iya itu mungkin.
Quazi Irfan
7
Melalui teknik apa?
Jim Buck

Jawaban:

15

Ya itu mungkin. Namun, itu tidak terlalu bermanfaat.

Pertama, kecuali Anda memiliki akses ke ekstensi NV_draw_buffers (seperti namanya, ini hanya NVIDIA. Jadi kecuali Anda menjalankan pada Tegra, Anda tidak memilikinya), objek framebuffer di bawah ES 2.0 hanya dapat merender ke satu gambar pada suatu waktu. Jadi untuk menghasilkan buffer-G Anda, Anda perlu membuat adegan Anda beberapa kali, sehingga menghilangkan salah satu keuntungan dari rendering yang ditangguhkan.

Kedua, bandwidth pada platform seluler tidak sama dengan yang Anda dapatkan bahkan pada GPU kelas menengah. Dan bandwidth sangat penting untuk membuat rendering yang ditangguhkan (untuk banyak lampu) bermanfaat. Tanpa bandwidth itu, cahaya melewati benar-benar akan sakit, kinerja-bijaksana.

Ketiga, perangkat keras PowerVR benar-benar tidak dirancang untuk hal semacam ini. Ini mengoptimalkan rendering dengan perangkat keras rendering berbasis ubin. Jadi rendering yang ditangguhkan di atas itu akan kurang membantu daripada dalam arsitektur konversi pindai tradisional.

Nicol Bolas
sumber
6

Masalah utama adalah Fillrate. Pada GPU seluler, laju pengisian Anda rendah sehingga Anda tidak dapat melakukan Peneduhan bayangan secara realtime pada resolusi asli.

Di iPhone 4 & iPad 1, pengisian hanya konyol. Satu-satunya perangkat iOS dengan fillrate yang baik adalah iPad 2, tetapi saya ragu ada cukup ... Di android, hanya perangkat Tegra yang memiliki GL_NV_draw_buffers untuk menggunakan MRT tetapi fillrate juga sangat rendah. Mali 400 nampaknya memiliki tingkat pengisian terbaik. Jika Anda ingin menangis, cobalah mengisi kotak warna pada resolusi layar penuh 4 kali ... Banyak perangkat tidak dapat melakukannya 60 fps.

Pada GPU desktop, Anda memiliki 10 kali (atau lebih) fillrate sebagai mobile gpus. Jangan lupa bahwa GPU seluler menggunakan memori yang sama dengan CPU dan Anda tidak memiliki memori khusus.

Ada beberapa contoh di WebGL (API yang sama) sehingga bukan batasan dari API.

Ellis
sumber
1
+1 untuk mengisi kelemahan. Saya bahkan tidak bisa membuat Gaussian blur berjalan pada resolusi 1536x2048 pada 60fps (segera menabrak frame rate turun menjadi 30fps, bahkan dengan hanya 4 sampel)
bobobobo
1
Saya pikir ini sangat tergantung pada seluk beluk implementasi Anda, dan memahami apa yang paling berdampak pada perangkat keras seluler. Sebagai contoh, orang-orang ini melakukan DoF dengan kinerja sedang pada tahun 2012.
Engineer
1

Benar-benar Anda harus mempertimbangkan apa minimum absolut yang Anda butuhkan untuk penyaji tangguhan. Jika Anda kembali ke pencahayaan yang ditangguhkan itu mengurangi jumlah data yang perlu disimpan dalam GBuffer, dan itu benar-benar jauh lebih murah daripada rendering setengah adegan 3 kali atau lebih untuk mendukung jumlah lampu yang rendah.

Saya akan menggunakan format GBuffer berikut:

  • Gunakan kembali penyangga kedalaman untuk izin pencahayaan, tidak yakin seberapa luas ini didukung pada perangkat seluler, tetapi ini adalah tekstur kedalaman gratis.
  • Sebuah tekstur GBuffer tunggal, di dalamnya saya akan menyimpan: Normal U, Normal V, Param 0, Param 1. Pengkodean Lambert-Azimuthal terlihat sangat bagus untuk normals dan mengompresnya menjadi hanya dua komponen, relatif murah untuk meng-encode dan decode juga.
  • Dua parameter untuk variabel pencahayaan banyak, bisa menggunakan satu sebagai enumerasi untuk beberapa fungsi pencahayaan jika perangkat keras bekerja dengan baik dengan percabangan dinamis.

Pencahayaan yang ditangguhkan mirip dengan rendering yang ditangguhkan, kecuali Anda membuat adegan dua kali:

  1. Render Geometry Depth, Normals, dan Parameter Pencahayaan ke dalam GBuffer.
  2. Render Lights ke dalam buffer akumulasi.
  3. Render Geometry dengan material shader, gabungkan pencahayaan Anda di sini juga. Jika keahlian Anda dalam menggunakan operator persamaan pencahayaan terbalik Anda dapat melakukan BANYAK hal yang sangat keren dengan langkah ini.
  4. Lakukan post-processing yang Anda mampu, pastikan untuk menyalahgunakan kedalaman dan tekstur normal sampai mati di sini demi efisiensi.

Tentang menyimpan hasil pencahayaan. Saya sudah suka menyimpan warna yang tersebar dan luminer spekulatif sehingga akumulasi buffer hanya perlu tekstur warna standar 32-bit. Anda dapat memperkirakan warna specular dengan menghitung kroma dari warna difus dan menggabungkannya dengan luminer spekuler.

Namun bagian terpenting adalah menggunakan buffer kedalaman-stensil sepenuhnya, pastikan Anda tidak merender kode pencahayaan di tempat yang tidak diperlukan. Saya bahkan melangkah lebih jauh dengan menambahkan beberapa pernyataan buangan ke dalam shader fragmen dengan persyaratan yang akan menurunkan visibilitas cahaya di bawah rentang yang dapat ditampilkan perangkat (1e-3 biasanya merupakan cutoff aman).

Kronosifter
sumber
discardbenar-benar buruk untuk saluran pipa berbasis ubin yang banyak / sebagian besar GPU seluler digunakan.
Insinyur
1

Pertimbangkan pencahayaan yang ditangguhkan. Singkatnya, pencahayaan yang ditangguhkan adalah teknik yang menggunakan versi pengurangan bayangan yang ditangguhkan untuk menghitung peta cahaya ruang layar. Dalam lintasan kedua, geometri ditampilkan kembali menggunakan peta cahaya screenspace sebagai informasi pencahayaan.

Teknik ini digunakan untuk mengurangi ukuran G-Buffer, karena dibutuhkan lebih sedikit atribut. Ini juga memberi Anda keuntungan, bahwa G-Buffer dan lightmap screenspace dapat memiliki resolusi lebih rendah daripada layar.

Saya telah menerapkan renderer berbasis GLES 2.0 yang ketat (meskipun bersifat eksperimental), dan saya berhasil merebus G-Buffer menjadi satu tekstur RGBA (ya, saya menggunakan tekstur2D alih-alih renderbuffer). Itu berisi ruang layar peta normal + buffer kedalaman di saluran alpha (yang dikompresi menggunakan logaritma, sejauh yang saya ingat).

Atribut posisi (disebut dunia di sini) dapat dihitung selama lintasan penerangan menggunakan fakta, bahwa dalam proyeksi perspektif, .xy dibagi dengan .z , sehingga:

xyfrkamustkamum=xywHairld/zwHairld

Saya memperkirakan atribut posisi xy dengan melakukan:

xywHairld=xyfrkamustkamumzwHairld

Catatan: Saya harus melakukan penyesuaian lebih lanjut tergantung pada pengaturan matriks proyeksi.

Juga diperhatikan adalah, bahwa aku mampu menghilangkan .z komponen dari vektor normal, karena saya bisa merekonstruksi .z dari .xy sejak vektor normal dinormalisasi sehingga:

x2+y2+z2=1x2+y2+z2=1z2=1-(x2+y2)z=1-(x2+y2)

Dengan menggunakan teknik ini, saya dapat membebaskan saluran lain di RGBA G-Buffer saya dan menggunakannya untuk menyimpan ruang layar peta-spekuler (atau kilau, jika Anda mau).

Simon Schmidt
sumber
BTW: Penyaji saya tidak terikat pada mesin game mana pun. Itu hanya demo dunia halo, rendering Suzanne.
Simon Schmidt
0

Ya, itu sangat mungkin. Tingkat pengisian tidak menjadi masalah karena chip grafis seluler dirancang untuk menangani layar resolusi sangat tinggi. Faktanya, rendering yang ditangguhkan membantu dengan ini karena perhitungan pencahayaan Anda tidak tergantung pada kompleksitas adegan, sehingga penarikan berlebih tidak menyebabkan perlambatan. Berikut ini adalah implementasi saya pada iPad generasi keempat: http://www.youtube.com/watch?v=K4X1oF6b4V8

Jika Anda ingin empat kali kinerja, hanya setengah dari resolusi tekstur yang Anda render. Saya benar-benar tidak dapat melihat perbedaan dengan grafik 3D pada layar retina.

Chip grafis seluler sangat bagus dalam rendering yang ditangguhkan karena cara mereka menangani render-ke-tekstur. Tidak seperti kartu grafis PC, yang biasanya menghasilkan hit kinerja besar ketika Anda mulai merender ke tekstur, bukan konteks jendela, grafik seluler dirancang untuk melakukan ini tanpa hit kinerja. Jadi, Anda mendapatkan skalabilitas penyaji tangguhan, tanpa penalti kinerja awal yang Anda alami pada kartu grafis desktop.

Pada saat implementasi saya, OpenGLES tidak ada render ke beberapa target, jadi saya harus menggambar warna layar dan normal dalam lintasan yang terpisah. Ini mungkin diperbaiki di versi OpenGLES yang lebih baru, tetapi tidak tahu apakah solusi belum tersedia di perangkat keras seluler konsumen.

JoshKlint
sumber
3
"Chip grafis seluler sangat bagus dalam rendering yang ditangguhkan karena cara mereka menangani render-ke-tekstur. Tidak seperti kartu grafis PC, yang biasanya menimbulkan hit kinerja besar ketika Anda mulai merender untuk tekstur daripada konteks jendela, grafis seluler adalah dirancang untuk melakukan ini tanpa hit kinerja. " Itu pernyataan besar di sana. Apakah Anda memiliki referensi yang memiliki reputasi baik untuk mendukung klaim ini?
Panda Pajama