Bagaimana saya bisa menekuk objek di OpenGL?

11

Apakah ada cara seseorang dapat menekuk objek, seperti silinder atau pesawat menggunakan OpenGL?

Saya seorang pemula OpenGL (saya menggunakan OpenGL ES 2.0, jika itu penting, meskipun saya curiga, matematika paling penting dalam kasus ini, jadi entah bagaimana ini versi independen), saya memahami dasar-dasarnya: menerjemahkan, memutar, mengubah matriks, dll Saya bertanya-tanya apakah ada teknik yang memungkinkan Anda untuk benar-benar mengubah geometri objek Anda (dalam hal ini dengan menekuknya)?

Setiap tautan, tutorial, atau referensi lain disambut baik!

Valentin Radu
sumber

Jawaban:

11

Apa yang perlu Anda lakukan untuk "membengkokkan" suatu objek adalah menerapkan kombinasi terjemahan / rotasi / penskalaan yang sesuai hanya pada beberapa subset dari simpul objek yang dipermasalahkan - mungkin menimbang transformasi tersebut sesuai.

Melakukan ini adalah cara yang tampak menyenangkan akan mengharuskan menggunakan lebih banyak simpul daripada yang mungkin diperlukan untuk menggambarkan mesh asli. Misalnya, sebuah silinder sederhana mungkin hanya memiliki simpul di kedua ujungnya, tetapi jika Anda ingin silinder itu ditekuk di tengah, Anda juga perlu simpul di sana.

Jika semua yang Anda minati sangat spesifik, deformasi satu kali dari bentuk yang sangat sederhana (seperti bidang yang disebutkan sebelumnya), Anda mungkin bisa melakukan ini secara manual. Sebagai contoh, tentukan "tikungan poros" untuk pesawat Anda dan hitung transformasi yang sesuai untuk setiap baris simpul bidang untuk mencapai rotasi yang tepat tentang sumbu tekuk itu tergantung pada jaraknya, dan kemudian terapkan itu pada geometri (mungkin pada CPU seperti itu akan menjadi yang paling mudah, paling tidak pada awalnya). Tetapi teknik seperti itu tidak akan skala dengan baik dan akan sangat membosankan.

Karena bisa jadi sangat rumit untuk mengetahui dengan benar cara membobot transformasi ke masing-masing simpul individu dalam satu set untuk mencapai deformasi yang diinginkan (terutama untuk objek yang lebih praktis dan rumit), banyak permainan menggunakan teknik yang disebut animasi kerangka . Pada tingkat tinggi ini melibatkan mengaitkan set geometri yang terpisah ("kerangka") dengan jaring Anda. Geometri itu mewakili tulang-tulang objek Anda, dan Anda mendefinisikan (sering dalam alat pemodelan) pemetaan antara simpul dari model nyata dan tulang-tulang kerangka - tulang mana yang dikaitkan dengan setiap titik, dan seberapa besar tulang itu mempengaruhi deformasi. dari titik itu. Kemudian kerangka dianimasikan secara langsung, dan animasi dipindahkan ke model nyata melalui hubungan antara tulang dan simpulnya.

Biasanya dalam teknik ini, pemetaan antara kerangka dan jaring nyata didefinisikan pada waktu produksi aset. Animasi juga dapat dibangun kemudian, atau mereka dapat dibangun secara prosedural saat runtime. Penerapan transformasi animasi ke jala nyata terjadi saat runtime. Secara umum tidak ada simpul baru yang dihasilkan pada saat runtime, yang berarti kisaran deformasi yang tampak baik secara implisit diperbaiki di mesh ketika awalnya dibuat.

Secara teori, kita juga bisa menerapkan tessellation dan subdivisi ke mesh pada saat runtime berdasarkan analisis transformasi dalam animasi, dan dengan demikian menghasilkan simpul yang tepat untuk membuat animasi yang tidak perlu direncanakan. Saya tidak sadar, begitu saja, tentang makalah tentang hal ini.

Lihat juga:

Vaillancourt
sumber
9

Untuk matematika sebenarnya dari warping, ini bisa menjadi sangat rumit, mengapa Anda tidak mulai dari sini? .

Sekarang saya akan berbicara tentang bagaimana Anda dapat menerapkan ini, dengan asumsi Anda sudah mendapatkan matematika untuk bagaimana Anda akan melakukan deformasi.

2 cara:

1) Setiap frame, kunjungi setiap titik dalam model silinder dan offset dengan beberapa cara.

2) Mengimbangi simpul dalam shader vertex saat Anda merender. OpenGL ES 2.0 mendukung vertex shaders. Jadi, Anda beruntung.

Apakah Anda ingin hanya membengkokkan objek seperti yang muncul di layar , atau Anda ingin membengkokkan objek sehingga setiap objek dalam permainan tahu bahwa itu telah cacat?

Jika Anda membengkokkan objek dalam vertex shader, maka itu terjadi hanya sesaat sebelum tampilan / rasterisasi , jadi ini berarti tidak ada objek game yang akan tahu tentang deformasi . Ini bagus jika Anda hanya membuat screen saver, atau jika deformasi sangat kecil sehingga tidak berdampak pada bentuk objek yang dapat di collidable.

Ketika Anda membelokkan geometri dalam vertex shader , simpul asli dari model sebenarnya tidak bergerak , (mereka hanya tampak bergerak ).

Deformasi pada vertex shader

Tidak diketahui:

tidak cacat

Cacat

cacat

Ini dari bab 6 tutorial cg , (program # 14).

Kode shader untuk menghasilkan deformasi ini adalah sesuatu seperti

// choose a displacement amount
float displacement = scaleFactor * 0.5 * sin(position.y * frequency * time) + 1 ;

// displace it in the direction of the normal
float4 displacementDirection = float4(normal.x, normal.y, normal.z, 0) ;

// move the vertex
float4 newPosition = position + displacement * displacementDirection ;

// transform (as normal)
oPosition = mul(modelViewProj, newPosition) ;

Jadi Anda dapat melihat, ini terjadi KANAN SEBELUM tampilan (vertex shader terjadi pada GPU) sehingga kode CPU praktis tidak memiliki cara untuk mengakses posisi vertex yang diubah (ada cara untuk mengirim data dari GPU ke CPU (terutama melalui tekstur) tetapi kami tidak akan pergi ke sana).

bobobobo
sumber
8

Apa yang Anda coba capai pada dasarnya adalah subset dari topik deformasi mesh. Tetapi karena Anda seorang pemula, saya khawatir informasi seperti ini mungkin agak terlalu aneh untuk saat ini. Saya akan mencoba untuk meletakkan konsep dasar sekalipun.

Untuk melakukan ini, Anda perlu dua hal:

  1. Jala Anda perlu memiliki simpul yang cukup untuk Anda transformasikan. Misalnya, jika itu adalah pesawat, Anda harus memastikan itu benar-benar dibuat sebagai semacam kisi, dengan banyak simpul untuk Anda ubah bentuknya. Hal yang sama dengan silinder. Mungkin untuk mencapai ini saat runtime dengan tessellation tapi saya tidak tahu banyak tentang subjek.
  2. Anda perlu menggunakan vertex shader untuk mengubah bentuk simpul. Pada dasarnya vertex shader akan menghitung posisi akhir yang diubah dari setiap vertex, sehingga Anda dapat mengambil kesempatan untuk menerapkan deformasi apa pun pada mereka.

Saya tidak yakin seberapa membantu hal itu, tetapi lihatlah sumber daya OpenGL ini, karena sepertinya ini adalah hal yang Anda butuhkan:

http://www.ozone3d.net/tutorials/mesh_deformer_p3.php#part_3

Tangkapan layar dari tautan itu:

masukkan deskripsi gambar di sini

Edit

Baru saja melihat jawaban Josh dan saya setuju, animasi kerangka juga merupakan cara yang sangat elegan untuk merangkum masalah ini, terutama ketika deformasi Anda mulai menjadi lebih kompleks dan lebih sulit untuk direpresentasikan secara matematis.

Tapi ingat, kedua poin di atas masih berlaku - Anda hanya dapat mengubah bentuk simpul, jadi jelas mereka harus ada di tempat pertama, itulah sebabnya mesh Anda perlu memiliki jumlah kepadatan titik yang cukup. Dan biasanya vertex shader yang mendorong animasi skeleton dan melakukan vertex blending dan semacamnya.

Dan omong-omong, Anda dapat melakukan ini pada CPU juga, tetapi saat ini biasanya merupakan pilihan yang lebih baik untuk melakukannya pada GPU, itulah sebabnya saya menekankan vertex shader, dan Anda harus melihatnya. Sebenarnya tidak terlalu sulit diprogram daripada melakukannya di CPU.

David Gouveia
sumber