Bagaimana cara membuat efek paralaks 2.5d?

8

Saya memiliki latar belakang yang layak dalam grafik dan pemrograman 3D, tetapi saya baru dalam pengembangan game. Saat ini saya sedang mengeksplorasi berbagai kemungkinan dan saya benar-benar ingin membuat game RPG. Saya sedang berpikir tentang tampilan isometrik 2D klasik, tapi saya sangat suka bagaimana Diablo 2 terlihat dan terasa untuk dimainkan.

Pertanyaan saya adalah - bagaimana saya bisa mencapai efek paralaks Diablo 2 ? Semuanya terlihat digambar tangan dengan lampu dan bayangan yang dipanggang dan terlihat mengagumkan, tetapi ketika Anda bergerak di sekitar Anda melihat beberapa perspektif .

Sebagai contoh, katakanlah saya menggambar aula besar dengan kolom di Photoshop dengan perspektif ortografis (gaya seni piksel klasik, hanya garis paralel). Bagaimana saya memberi efek paralaks pada adegan ini ketika karakternya bergerak? Jika saya menggunakan sprite menghadap kamera untuk semua hal itu mungkin akan terlihat OK di kejauhan, tapi itu akan benar-benar palsu ketika karakter mendekati kolom (silinder) misalnya.

Ada saran? Bagaimana Blizzard membuat efek paralaks dalam Diablo 2?

Lihat tangkapan layar ini: http://guidesmedia.ign.com/guides/10629/images/act2tombs.jpg

Nikolay Dyankov
sumber
Ini kamera bergaya RTS. google.com/#q=rts+game+camera
LiquidFeline
1
Saya tidak bertanya tentang kamera, itu adalah kamera perspektif pada sudut tertentu dari tanah, itu jelas. Pertanyaan saya adalah tentang lingkungan dan bagaimana cara kerjanya.
Nikolay Dyankov
1
Bukan duplikat, AoE tidak memiliki efek paralaks. Luangkan waktu Anda untuk membaca seluruh pertanyaan saya lagi.
Nikolay Dyankov
1
Tolong berhenti menempel hidung Anda dalam pertanyaan ini jika Anda tidak punya jawaban. Anda jelas tidak mengerti pertanyaan itu jadi berhentilah mengeditnya!
Nikolay Dyankov
2
Siapa idiot yang menurunkan ini? Beberapa orang di situs ini benar-benar tidak memiliki petunjuk! Hanya seseorang yang tidak pernah bermain Diablo II yang bisa kalah, saya kira!
Insinyur

Jawaban:

5

Ini adalah jawaban yang panjang, tetapi sebenarnya premis dasar divide-by-camera-z sangat sederhana: Semakin jauh sesuatu menjauh dari Anda, semakin kecil tampilannya. Juga, jarak yang lebih kecil antara dua hal muncul.

Positions (Tidak wajib dibaca jika Anda menggunakan Unity!)

Pertama, Anda perlu merender posisi / poin yang menggunakan perspektif yang benar.

Posisi berbaring di pesawat datar. Anda menginginkan sesuatu seperti gambar di sebelah kanan ... pertimbangkan sudut-sudut ubin sebagai titik / posisi sampel.masukkan deskripsi gambar di sini

Inilah cara Anda mendekati transformasi poin:

  • Sistem koordinat Anda adalah sebagai berikut: zberjalan positif ke layar, sementara xberjalan dari kiri ke kanan dan yberjalan ke bawah. Kamera z adalah dunia z. Itulah jalan pintas yang membuat ini jauh lebih mudah daripada menulis mesin 3D penuh. Kelemahan? Kamera tidak dapat mengubah orientasi (meskipun dapat mengubah posisi).
  • Simpan posisi 3D awal kamera Anda. Masukkan kembali (minus z) dari asal dunia.
  • Simpan koleksi poin 3D di bidang xz (berikan y=0). Cobalah untuk pusat mereka di seluruh dunia asal di x, (0,0,0), yaitu dari negatifn ke positifn . Ini untuk memusatkan mereka di viewport, saat rendering dimulai.
  • Pertimbangkan titik awal / titik piksel yang merencanakan menjadi pusat layar.
  • Tentukan jarak dari kamera di mana 1 unit ruang dunia = 1 piksel. Ini berarti jika Anda memindahkan kamera hanya 1 unit ruang dunia, objek apa pun yang berjarak 10 unit akan bergeser hanya 1 piksel - cukup jauh! Simpan jarak ini sebagai konstantaK .
  • Sekarang, untuk setiap titik, render pada posisi menggunakan rumus berikut: screenPosition(x,y) = screenOrigin + (worldPosition(x,y) - cameraPosition(x,y)) / ((worldPosition(z) - cameraPosition(z)) * K)... seperti yang Anda lihat, kami mendasarkan posisi render pada z-jarak antara titik saat ini dan kamera.

  • Mainkan dengan posisi z kamera sampai Anda melihat poin yang diberikan. Tapi yang akan Anda lihat adalah bahwa semua poin akan ditampilkan di garis tengah layar. Jadi kita perlu memperbaikinya. Coba K=1vs. K=10untuk melihat perbedaannya.

  • Anda sekarang dapat memindahkan kamera yuntuk melihat bagaimana kamera Anda bergerak di atas dan di bawah bidang titik (yaitu titik-titik akan membuat, perspektif-benar, di bawah atau di atas garis tengah layar, masing-masing, saat Anda menggerakkan kamera ke atas dan ke bawah ).

Ini adalah pedoman yang sangat kasar. Ada beberapa detail implementasi yang akan Anda lakukan. Langkah pertama adalah hanya untuk menampilkan sesuatu, kemudian mengubah dari sana. Satu detail yang terlintas dalam pikiran adalah bahwa jika Anda ingin kamera terlihat lebih seperti melihat ke bawah, maka Anda perlu menggeser asal perenderan Anda ke atas, lebih dekat ke bagian atas viewport. Detail lain adalah bahwa jarak Anda antara kamera dan titik mungkin perlu memasukkan rasio trigonometri ... Saya pikir menggunakantan menawarkan perspektif yang lebih realistis. Tidak ingat dengan jelas tentang ini, tetapi Anda akan segera melihat apakah perspektifnya terlihat aneh dan dapat beradaptasi sesuai itu. Saya tidak bisa lebih spesifik tanpa menulis ulang sampel.

Per-billboard bengkok dan scaling (diperlukan)

Sekarang Anda dapat melihat perspektif di antara set posisi titik Anda, dan dapat menambahkan, menghapus, atau memindahkan posisi (seperti dengan karakter) sesuka Anda, Anda juga perlu menerapkan perspektif pada masing-masing sprite yang akan di-root pada posisi tersebut.

Di D2, selalu tampak bagi saya sebagai fungsi lungsin lateral sederhana yang diterapkan lebih pada papan reklame yang berada di bawah layar, daripada pada yang di atas, dan juga lebih saat Anda menjauh dari garis tengah yang mengalir ke bawah. layar.

Mungkin ada beberapa penskalaan vertikal yang diterapkan pada papan iklan juga, misalnya. pohon semakin pendek dibandingkan dengan skala yang diharapkan, lebih dekat bagian bawah layar (untuk membuatnya tampak seolah-olah kamera melihat ke bawah pada pohon - saya menemukan pohon Tristram menjadi cara terbaik untuk menjelajahi ini dengan aman, kembali ke hari ;) ).

Apa yang akan saya lakukan adalah:

  1. Atasi fungsi penskalaan dasar berdasarkan jarak dari kamera ke ground di berbagai titik. Jadi, Anda akan memiliki penskalaan yang serupa untuk setiap garis pemindaian.
  2. Hanya setelah saya melakukan itu, barulah saya akan melihat lungsin lateral - pertama berdasarkan jarak dari garis tengah berlari di layar.
  3. Terakhir saya akan menyelidiki bagaimana lungsin lateral dipengaruhi oleh jarak ke bawah layar (dan saya merasa bahwa rasio trigonometri sederhana akan menjadi inti dari hal ini).

Perspektif-memperbaiki ubin (Tidak wajib dibaca jika Anda menggunakan Unity!)

Mudah-mudahan di atas akan memberi Anda diposisikan dengan benar, melengkung "berdiri" sprite (yaitu objek yang duduk tegak lurus dengan bidang tanah, seperti karakter, pohon, rumah).

Namun, Anda juga perlu mempertimbangkan cara membuat ubin lantai berubah bentuk dengan benar dan mulus. Dan saya pikir Anda akan menemukan itulah bagian yang, khususnya, membutuhkan GPU pada D2. Saya ingat bahwa pada sistem tanpa GPU, opsi perspektif dinonaktifkan. Alasan untuk ini hampir pasti adalah bahwa GPU dapat mengambil permukaan tekstur dan menerapkan koreksi perspektif dengan sangat cepat, tanpa ada gangguan antara ubin, dan tanpa khawatir melakukan transformasi non-affine dalam kode aplikasi, yang melibatkan beberapa matrik matematika dan bisa sedikit mahal:

masukkan deskripsi gambar di sini

Saya punya beberapa saran bagi Anda untuk berurusan dengan ini:

  • (Unity) Gunakan Unity Camera untuk memasok render bidang datar, permukaan bertekstur, lalu tangani distorsi papan reklame secara terpisah berdasarkan posisi layar.
  • Lakukan logika ini (atau bahkan semua logika render) dalam GPU shaders.
  • Jangan gunakan ubin tanah sama sekali. Sebagai gantinya, cukup gunakan sprite titik - seperti karakter itu sendiri - pada bidang yang berwarna seragam (misalnya hijau untuk rumput) untuk memberikan detail agar bidang tersebut tidak terlihat kusam. Ini akan meningkatkan biaya rendering Anda, tetapi ini tentunya cara termudah untuk mengatasi masalah ini.
Insinyur
sumber
Sayangnya satu-satunya hal yang saya mengerti adalah "penskalaan vertikal". Mungkin saya harus tetap berpegang pada isometrik 2D untuk saat ini.
Nikolay Dyankov
Ok, izinkan saya menyederhanakan pertanyaan saya, bagaimana Anda membuat 3d silinder terlihat 2d? Sesuatu yang ditarik seperti ini - media.web.britannica.com/eb-media/49/63049-004-C560D293.gif
Nikolay Dyankov
Tidak ada perspektif tentang itu. Ingin berdiskusi dalam obrolan?
Insinyur
Tentu, silakan mulai obrolan, saya tidak tahu bagaimana :)
Nikolay Dyankov
^ atas halaman ^
Insinyur