Gim baru dengan suasana lama di Three.js

Ada banyak penggemar game lama. Dan mereka tidak menolak untuk mengeluarkan air mata nostalgia dan tidak, tidak, tetapi bermain "Arkanoid", "Pakman" atau "Prince of Persia" seperti dua puluh, tiga puluh, empat puluh atau - menggantikan angka yang diinginkan - tahun yang lalu. DOS-box dan emulator - untuk membantu mereka. Ya, apa yang ada di sana, saya baru-baru ini menyaksikan aliran 2D "Prince of Persia" pertama di YouTube, di mana streamer yang agak muda, setelah melewati rintangan fana lain, melambaikan keringat dari dahinya dengan tangannya, berkata: "Saya tidak pernah begitu takut dalam permainan komputer." ". Artinya, bahkan anak-anak muda dapat menghargai hardcore dan kesejukan dari game-game lama.


Saya pikir, mengapa tidak membuat game baru dengan gaya yang sama? Ya, ada berbagai remake dan klon. Juga, game modern dalam gaya kegembiraan seni pixel. Namun, semua dari mereka, sebagai suatu peraturan, mengulangi pencarian, mekanik, dan kadang-kadang bahkan benar-benar level desain game-game lama, berdasarkan yang mereka buat. Yah, atau, sebaliknya, mereka menawarkan plot dan lokasi yang sama sekali baru, yang hanya merupakan stylization visual "antik". Tetapi bagaimana jika Anda membayangkan apa bagian baru dari permainan lama jika mengikuti seri terakhir? Saya memutuskan untuk membuatnya.

Saya mengambil platformer 2D dan menambahkan grafik 3D di sana, sambil mempertahankan tampilan samping klasik. Dia membangun labirin baru, memunculkan pencarian baru, memperkenalkan tugas, dan mengimplementasikan slot inventaris. Sedikit ragam perasaan ruang, menambahkan belokan 90 derajat. Mungkin, di masa kuno itu, sebelum transisi total game dalam 3D dengan tiga derajat kebebasan, hal seperti ini bisa saja keluar.

Karena saya gemar menulis game untuk browser, saya memutuskan untuk membuat game untuk browser. Karena kekhususannya, itu tidak memiliki jumlah gila poligon, setidaknya ditampilkan di layar pada saat yang sama, tidak ada dunia terbuka. Karena itu, semua ini tidak akan memuat browser. Untuk menampilkan grafik 3D, saya memilih perpustakaan Three.js (WebGL) favorit saya dengan pembungkus saya sendiri. Tidak ada perpustakaan lain yang digunakan, dan kode ditulis dalam javascript murni.

Three.js dan masalah yang saya temui


Pengembang mesin grafis 3D secara berkala, sekitar sekali setiap dua tahun, merilis versi baru dari kreasi mereka. Dalam kasus pustaka skrip Three.js, pengembang senang kami dengan pembaruan pada frekuensi panik - sekitar sebulan sekali. Pada saat penulisan, versi terbaru memiliki nomor 106. Tampaknya ini baik-baik saja. (Tidak)

Mengapa tidak ada orang yang berpikir tentang kompatibilitas ke belakang? Ketika pengembang Three.js mengganti nama ambient properti material, saya menyadari, "Houston, kami memiliki masalah . " Oke, katakanlah tidak sulit bagi saya di seluruh kode saya untuk mengubah kata "ambient" menjadi "warna" dengan pencarian-ganti. Tetapi ketika mereka mengesampingkan kemungkinan sumber cahaya menciptakan bayangan tanpa penerangan seperti itu, saya menyadari bahwa sekarang pendaratan Elang berada dalam bahaya nyata, dan pangkalan Calm perlahan mulai berubah menjadi pangkalan Rabies . Namun, ternyata kemudian, itu tidak terlalu buruk ...

Faktanya adalah bahwa dalam game saya, selain cahaya yang dipanggang, pencahayaan dinamis juga digunakan. Jumlah sumber dinamis dalam adegan 3D sangat memengaruhi kinerja.


Saya memilih sejumlah sumber dalam pengaturan game - dari 1 hingga 7. Dan tergantung pada kekuatan kartu video, Anda dapat mencoba nilai yang berbeda.

Ada juga array yang berisi koordinat dan karakteristik masing-masing sumber - intensitas, warna, dan sebagainya. Itu berfungsi seperti itu. Saat bergerak di sekitar dunia game di kotak tertentu di sekitar pemain, jumlah sumber cahaya yang ditentukan dalam pengaturan dengan karakteristik yang ditentukan akan menyala. Artinya, sumber cahaya tampaknya mengikuti pemain (di sekitarnya) oleh awan.

Jadi, Houston, apa masalah kita? Saya melaporkan.

Masalah nomor 1: bayangan


Sumber cahaya menciptakan bayangan. Saya perhatikan bahwa bayangan dari sumber cahaya titik mengkonsumsi lebih banyak sumber daya daripada bayangan yang diarahkan (lampu sorot). Dan ini bisa dimengerti: dalam kasus sumber titik, bayangan dilemparkan ke segala arah, dan terarah - hanya dalam kerucut yang diberikan. Namun, saya menyarankan bahwa ketika bayangan di segala arah tidak diperlukan, maka dua sumber dapat digunakan sekaligus: satu titik hanya akan menciptakan pencahayaan, dan satu arah hanya akan membuat bayangan di arah tertentu. Ini sempurna untuk gim saya dan, ternyata, benar-benar menghemat daya komputasi.


Piramida membatasi area di mana bayangan dapat muncul.

Tapi inilah masalahnya, dimulai dengan versi three.js r73, sumber cahaya terarah tidak lagi hanya bisa membuat bayangan, sekarang selalu memberikan pencahayaan juga. Dan cahaya darinya menyebar di dalam area, juga bayangan. Tidak mungkin untuk menghapus sumber titik dan hanya meninggalkan yang terarah: Saya perlu penerangan ke segala arah. Dan menggunakan kedua sumber, menyesuaikannya dengan kecerahan yang diinginkan, juga tidak berfungsi: maka objek di dalam kerucut akan menyala lebih terang. Penggunaan pencahayaan "jujur" dengan bayangan di segala arah memengaruhi kinerja gim secara fatal.

Dan mereka menghapus properti yang diperlukan dari sumber cahaya directional. Hanya Shadow, hanya karena penulis mesin menginginkannya.

Masalah nomor 2: nama properti


Saya memutuskan untuk memilih versi r71, di mana properti pencahayaan yang saya butuhkan masih ada. Mengapa tidak r72? Setelah semua, properti itu menghilang hanya dalam versi r73. Karena saya sudah menulis cukup banyak kode untuk memuat model 3D, animasi dan fisika untuk versi r71. Dan dalam versi r72, sejumlah besar nama properti telah berubah: ketik - shadowMap telah menjadi shadow.map, dll. Secara umum, saya juga tidak ingin mengubah nama semua ini. Dan perbedaan antara satu versi kecil. Jadi, kami tetap pada versi r71.

Masalah nomor 3: memanggang bayangan



Baked light dalam versi mesin yang berbeda juga terlihat berbeda. Saya tidak tahu apa yang mereka lakukan dengannya di sana, tetapi ketika menerapkan bayangan peta pada tekstur, kecerahan dan bahkan warna berubah secara dramatis. Secara umum, saya entah bagaimana menyelesaikan masalah ini dengan sub-mengejek mesin dalam kode GLSL dan mengatur koreksi warna otomatis di loader model 3D di tempat-tempat di mana bayangan peta digunakan. Ini berfungsi, tentu saja, hanya untuk versi r71. Untuk versi lain, Anda harus menggunakan beberapa parameter lain. Ini adalah alasan lain untuk tetap menggunakan versi r71.


Sebenarnya, tidak masuk akal untuk beralih ke versi terbaru, karena hasil pekerjaan, dibandingkan dengan yang lama, tidak berbeda secara mendasar dalam hal kinerja.

Bagus Sumber cahaya terarah hanya menciptakan bayangan. Saya bisa memanggang dan memuat bayangan ke perakitan di versi r71. Dan sekarang - penyergapan paling penting. Karakter.

Masalah 4: animasi kerangka


Itulah yang saya perjuangkan untuk waktu yang sangat lama. Secara total, saya menghabiskan beberapa minggu mencoba menemukan semacam algoritma yang berfungsi untuk mentransfer karakter dengan serangkaian animasi ke permainan.


Three.js versi terbaru tidak memiliki masalah ini. Di sana saya berhasil membuat model karakter animasi dalam layanan online yang terkenal, mengubahnya menjadi format gltf yang populer dan mengunggahnya ke tempat uji. Namun, jika versi baru dari Three.js menggunakan format gltf 2.0, maka milik saya hanya mendukung 1.0. Tampaknya, apa masalahnya, well, konversikan ke 1.0 dan unduh. Ternyata tidak sesederhana itu. Ternyata, ada beberapa variasi format gltf 1.0. Saya membutuhkan satu tempat, selain file model utama, dua file lagi dengan ekstensi * .glsl harus ada. Tetapi dalam kasus ini, format file utama dapat bervariasi ... Secara umum, saya tidak dapat menemukan konverter yang akan memenuhi semua parameter, terutama karena ia juga dikonversi dari format baru ke yang lama. Saya juga gagal menyelesaikan versi lama dari three.js to gltf 2.0 support: dukungan ini terlalu dalam pada kodenya, berakar pada matematika yang diimplementasikan secara berbeda di versi mesin yang berbeda ... Secara umum, gltf entah bagaimana tidak berhasil.

Saya mencoba menggunakan format .dae untuk model 3D. Akibatnya, model itu sendiri memuat, tetapi saya tidak bisa membuat animasi karakter berfungsi dengan benar. Ada juga masalah dengan tekstur.

Ternyata dengan format .md2. Karakter segera ditampilkan dan semua animasi bekerja dengan benar. Tapi, seperti yang saya mengerti, md2 adalah format model untuk Quake 2 dan seseorang mengimplementasikan dukungannya di Three.js hanya untuk bersenang-senang. Dan di mana mendapatkan model dalam format ini, dan bahkan lebih lagi, untuk merancang dan menyimpan karakter saya sendiri di dalamnya, saya tidak menemukannya.

Saya mencoba beberapa format lagi. Tetapi di bawah mereka, tidak ada bootloader untuk tiga. Js, tidak ada program untuk membuat pelestarian karakter mereka di dalamnya, maka mereka tidak mendukung animasi skeletal sama sekali.

Pangkalan "Rabies" tepat untuk mengubah nama pangkalan "Keputusasaan".

Sudah hampir putus asa dan berpikir untuk beralih ke versi baru mesin dengan mengorbankan kinerja (kisah sumber cahaya terarah), saya memutuskan untuk terakhir kalinya untuk menyiksa format json, yang sebenarnya saya mulai dengan. Tetapi untuk pertama kalinya, saya tidak dapat mengulangi proses konversi karakter dari file contoh yang datang dalam bundel Three.js dari format .blend asli ke .json di editor Blender 3D. Animasi-animasi itu rusak dan berperilaku entah bagaimana secara acak, dan dengan selusin variasi pengekspor dari Blender ke json, masing-masing bekerja dengan benar. Apalagi saya juga mencobanya di beberapa versi Blender. JSONLoader sendiri, yaitu model loader dalam format json, sekarang telah dihapus dari three.js. Saya memutuskan untuk melihat versi mana dukungannya telah berhenti, untuk mengambilnya dan sampel model 3D bukan dari versi saya, tetapi dari versi di mana dia masih. Dia ternyata r88. Dan lihat! Saya berhasil mereproduksi ekspor model uji di r71 dan semuanya, termasuk animasi karakter, bekerja dengan baik dalam permainan!

"Elang" mendarat dengan selamat.

Kemudian saya memutuskan untuk mengedit salah satu animasi dari karakter uji di Blender untuk melihat apakah saya bisa membuatnya sendiri. Nyebelin menunggu saya di sini. Animasi yang saya edit tidak ingin bekerja sama sekali di dalam game. Karakter membeku di posisi awal. Meskipun animasi lain bekerja tanpa masalah. Tapi ini sesuatu. Artinya, sekarang masalahnya adalah ketidaktahuan saya tentang beberapa nuansa mengedit animasi.

Lalu saya berpikir - bagaimana jika saya bertanya kepada penulis contoh ini bagaimana dia melakukannya. Tetapi mendapatkan penulis itu tidak mudah. Dia tidak memiliki kontak pribadi di Github. Pencarian untuk nama panggilan dan beberapa parameter lainnya dibawa ke Twitter-nya, namun, pesan pribadi di sana ditutup. Tetapi dari sana saya mengetahui bahwa dia adalah seorang profesor di beberapa universitas Amerika, dan pergi ke situs web lembaga pendidikan ini. Ternyata sang profesor terlibat dalam grafik 3D dengan murid-muridnya, menggunakan contohnya sebagai bahan metodologis. Lalu aku kembali ke Github dan memeriksa semua gudang. Di sini saya sedang menunggu kesuksesan. Seperti yang saya harapkan, contohnya disimpan dalam repositori terpisah. Dan bukan hanya salinan dari apa yang telah saya lihat dalam contoh three.js, tetapi sebuah contoh dengan hati-hati dilengkapi dengan instruksi (tampaknya, untuk siswa). Saya mengunduh arsip dan, mengikuti instruksi, mengulangi semuanya. Hore!

Ini adalah langkah kecil untuk kemanusiaan, tetapi lompatan besar untuk satu orang dan permainannya!

Tidak masalah, Houston!



Sekarang saya mengerti bahwa jika saya tetap menggunakan format ini, instruksi ini dan versi Three.js, JSONLoader, dan Blender ini dan melakukan semuanya dengan cara yang sama, saya dapat membuat dan memuat karakter saya ke dalam permainan browser. Berita baiknya adalah, meskipun menggunakan versi mesin yang lama, Anda dapat menggunakan versi terbaru editor 3D Blender dan membuat karakter apa pun dengan animasi. Saat itu Anda perlu mengekspornya menurut skema yang didefinisikan secara ketat menggunakan toolkit khusus ini.

Ya, saya perhatikan satu masalah lagi dengan versi baru Three.js: selama permainan, saat menggulir layar, untuk beberapa alasan, friez konstan diamati. Dan ini bukan karena peningkatan konsumsi sumber daya - prosesor dan kartu video tidak memuat 100%. Dan di r71 lama tidak ada aib seperti itu.

Sekarang tinggal melakukan permainan untuk editor karakter 3D dengan animasi. Dan, tentu saja, geometri levelnya. Saya tidak tahu berapa lama waktu yang saya perlukan. Namun sejauh ini saya baru saja mengumpulkan versi demo gratis di Webkit dan mengunggahnya ke toko aplikasi yang populer.

Sedikit tentang permainan


Nama. Saya menyebut permainan Percy Lancaster. Semuanya jelas di sini: "Saya seorang seniman, dan saya melihat begitu."

Bagaimana grafik dibuat . Saya membuat dua pesawat di editor 3D, mengatur jarak dari satu sama lain sehingga yang jauh tersembunyi di belakang yang terdekat, menarik tekstur batu pada mereka, memotong lubang di yang terdekat, dan kemudian menghapus bagian yang tidak perlu, yaitu, tidak terlihat, bagian. Kemudian dia membuat model pesawat untuk lantai dan langit-langit. Jadi itu ternyata menjadi koridor bagi pemain untuk berjalan. Saya mendiversifikasi lokasi dengan berbagai tekstur.


Dalam permainan itu sendiri tidak ada jenis seperti itu, hanya ada tampilan samping, dan tidak ada ruang hitam yang terlihat. Ini hanya pandangan umum koridor.

Saya memutuskan untuk membuat koridor berpotongan. Selama belokan, satu dinding koridor lainnya selesai, seluruh struktur berubah, dan kemudian dinding koridor pertama dihilangkan. Berdasarkan mekanika ini, saya juga berencana untuk membuat menara di mana Anda dapat menaiki tangga spiral.


Dengan grafik statis, sebenarnya, tidak ada masalah, itu mudah diekspor ke json dari editor 3D apa pun. Kesulitan, seperti yang telah saya sebutkan, muncul hanya dengan bayangan kue dan animasi karakter.

Performa. Dalam resolusi layar HD, yaitu, 1280x720, kartu grafis GT-730 saya yang tidak terlalu kuat dimuat sekitar 35-40%, dan prosesor Xeon E5440 dimuat sekitar 30%. Saya pikir ini lebih dari hasil yang dapat diterima.

OS Sejauh ini, demo hanya tersedia di bawah Windows sebagai perakitan di Webkit. Di masa depan saya berencana untuk meluncurkan versi browser. Saya menemukan fakta bahwa tidak semua browser menggulir layar dengan lancar. Saya masih perlu bekerja pada mengelola dan memanggil fungsi output grafis. Sementara itu, saya memilih Webkit versi 26.0. Beratnya sedikit dan semuanya bekerja dengan baik pada dirinya.

Suara. Suara sebagian diambil dari perpustakaan gratis, sebagian dihasilkan. Secara umum, mereka telah dibuat sejauh ini, "menjadi". Meskipun saya tidak terlalu peduli tentang mereka.

Video Level demo bagian penuh.


Paket


Saya berencana untuk pergi ke crowdfunding, dan menyewa seorang modeler 3D dengan uang yang terkumpul, yang akan menciptakan karakter dan animasi normal untuknya. Tetap saja, grafisnya bukan milik saya. Tapi sekarang saya tahu cara memperkenalkan karakter ke permainan saya.

Saya juga berencana meluncurkan versi browser untuk Chrome dan Firefox versi terbaru. Biarkan saya memberi tahu Anda sebuah rahasia, saya bahkan berhasil menjalankan game di MS Edge, tetapi untuk beberapa alasan tidak ada objek di mana tekstur bayangan panggang tumpang tindih, saya masih belum mengetahuinya. Selanjutnya, saya akan men-debug browser untuk Linux dan Android, dan jika saya mendapatkan perangkat apple untuk diuji seseorang, maka juga untuk browser di iOS dan MacOS.

Dalam jangka panjang - menulis perpustakaan Anda sendiri untuk bekerja dengan WebGL, seperti Three.js: Saya tidak suka mereka tiba-tiba mengubah nama properti dan menghapus fungsionalitas yang saya butuhkan. Sebaliknya, sebagian besar peluang besar yang ditawarkan Three.js tidak saya butuhkan.

Saya pikir nanti, ketika saya mencari tahu operasi permainan yang benar untuk semua browser pada OS yang berbeda, saya akan menulis artikel tentang ini dengan beberapa rincian teknis.

Source: https://habr.com/ru/post/id468261/


All Articles