Bagaimana animasi ditangani dalam OpenGL tidak langsung?

8

Saya seorang pemula untuk OpenGL modern. Saya nyaman dengan metodologi OpenGL langsung, tetapi saya belum pernah melakukan penggunaan serius VBO. Pertanyaan saya adalah tentang animasi. Dalam mode langsung, untuk mencapai animasi Anda hanya perlu melakukan streaming posisi vertex yang berbeda (diinterpolasi dari keyframe) di ruang objek.

Bagaimana ini dicapai dalam OpenGL tidak langsung? Jelas, mengunggah data VBO segar untuk setiap frame pasti akan memonopoli bus grafis. Saya belum menemukan literatur tentang cara modern untuk melakukannya. Memikirkannya, saya datang ke beberapa pilihan:

  • Atribut: animasi sebagai offset 3d. Untuk setiap frame, atribut offset yang berbeda (mungkin diinterpolasikan) dilewatkan untuk setiap vertex, diterapkan pada vertex yang sama setiap frame kunci.
  • Indeks: menyimpan kerangka kunci sebagai simpul absolut dan mengaksesnya melalui pengindeksan, menggunakan kumpulan simpul yang berbeda untuk setiap kerangka kunci. Saya menemukan pendekatan ini tidak mungkin, karena Anda tidak dapat mengakses keyframe yang berdekatan dan oleh karena itu tidak dapat melakukan interpolasi di antara mereka. Juga, sepertinya ide yang buruk untuk animasi prosedural.
  • Tekstur: ini mungkin sangat melar tetapi terdengar seperti solusi yang bagus untuk saya. Sekali lagi, animasi dianggap sebagai offset xyz untuk setiap titik. Setiap keyframe dapat disimpan dalam tekstur 1D di mana dimensi memetakan ke vertexID. Jika saya tidak salah, di OpenGL 4.0 Anda dapat mengakses tekstur dari shader apa pun, sehingga Anda bisa membaca tekstur ini dari vertex shader dan menerapkan setiap transformasi vertex. Tekstur 2D bisa menampung beberapa bingkai. Anda masih melakukan interpolasi (dan jika interpolasi bekerja untuk tekstur di luar fragmen shader, yang saya tidak yakin, Anda dapat interpolasi linear secara gratis!) Ini dapat diterapkan pada sistem animasi yang lebih kompleks seperti animasi tulang tanpa banyak usaha.

Apakah saya terlalu memikirkan ini? Adakah yang bisa menjelaskan?

kaoD
sumber

Jawaban:

5

Saya belum menemukan literatur tentang cara modern untuk melakukannya.

Itu umumnya karena "cara modern" untuk memiliki animasi karakter adalah dengan menggunakan kerangka tulang, bukan pencampuran verteks.

Namun, jika Anda bersikeras melakukan animasi berbasis vertex, Anda bisa. Cara paling sederhana adalah dengan hanya mengirim dua keyframe yang ingin Anda padukan sebagai atribut. Anda memiliki data posisi untuk semua berbagai kerangka kunci; cukup gunakan glVertexAttribPointer(atau glVertexPointerjika Anda bersikeras) untuk memilih frame kunci tertentu. Karena setiap keyframe harus memiliki data posisi disimpan dalam urutan yang sama (untuk posisi yang sesuai), mereka dapat menggunakan daftar indeks yang sama untuk rendering.

Shader mendapatkan dua atribut "posisi", satu untuk keyframe di depan waktu saat ini dan satu untuk keyframe sesudahnya. Anda juga akan lulus seragam yang menentukan berapa banyak campuran yang harus dilakukan di antara mereka. Anda menghitung posisi baru sebagai perpaduan antara dua kerangka kunci, dan kemudian melakukan transformasi biasa dari sana.

Nicol Bolas
sumber
Apakah Anda memiliki buku atau artikel yang direkomendasikan untuk dibaca untuk memulai belajar tentang menulis kode untuk menangani penimbangan tulang kerangka?
michael.bartnett
Saya mencari "bagaimana memindahkan simpul" bukan bagaimana melakukan animasi yang sebenarnya. Yah, itu tidak begitu berbeda dengan penimbangan tulang kerangka, setelah semua, turun ke simpul bergerak di sekitar, apakah itu diperhitungkan (vertex-blended) atau on-the-fly weighted weight. Apakah atribut satu-satunya cara untuk diam? Bukankah pendekatan berbasis tekstur masih layak, dan lebih cepat daripada memberikan banyak data untuk setiap titik setiap frame? (setidaknya kedua frame kunci per-tulang dan faktor campuran) Tekstur masih dapat menyandikan rotasi tulang, dan pencarian tekstur jauh lebih cepat daripada melewati atribut.
kaoD
Juga: "Karena setiap frame kunci harus menyimpan data posisinya [...] mereka dapat menggunakan daftar indeks yang sama untuk rendering." Bukankah itu tidak mungkin? Bagaimana saya bisa mengakses dua indeks untuk interpolasi antara? Bukankah vertex shader lupa satu sama lain, dan bahkan lebih ke indeks lain?
kaoD
@ kaoD: Tidak mungkin? Bukankah itu yang Anda lakukan saat ini untuk menghitung posisi simpul baru? Untuk setiap posisi di setiap susunan kerangka kunci, Anda menyatukannya dan menuliskannya ke OpenGL. Yang saya katakan adalah Anda memberikan array keyframe itu ke OpenGL dan membiarkan shader melakukan blending. Sedangkan untuk pencarian tekstur, dalam hierarki "hal-hal cepat di shaders", pencarian tekstur umumnya di bagian bawah . Atributnya, lebih atau kurang gratis .
Nicol Bolas
@NicolBolas: baik untuk mengetahui bahwa pencarian tekstur lebih lambat dari yang saya kira. Yang saya maksud dengan mustahil adalah bahwa, jika saya tidak salah, setiap simpul hanya dapat 'melihat' dirinya dalam shader, dan oleh karena itu tidak dapat mengindeks simpul lain atau mengakses array lain (keyframe.) Apa yang saya mengerti dari jawaban Anda adalah bahwa saya harus melewati dua posisi keyframe ini sebagai attribs untuk setiap vertex, bersama dengan seragam faktor campuran, tetapi kemudian saya tidak akan memiliki array vertex, bukan? Meskipun saya baru sadar Anda dapat menggunakan keyframe saat ini sebagai array vertex dan frame berikutnya sebagai array atribut, apakah ini yang Anda maksud?
kaoD