Cara membuat air terjun fisika 2D


8

Saya mencoba untuk membuat air terjun yang terlihat mirip dengan gambar pertama di bawah ini (silakan periksa video ini untuk ide yang lebih baik tentang apa yang ingin saya capai) dengan sifat fisika sehingga dapat bergerak atau mengelilingi objek dengan colliders di jalurnya (mirip dengan gambar kedua di bawah). Meskipun air terjun yang terhubung adalah 3d saya tertarik dengan implementasi 2d.

Perhatikan bahwa benda-benda itu dinamis dan beberapa bergerak sering karena itu air terjun harus membentuk kembali setiap bingkai. Benda-benda bergerak lambat baik bergerak ke posisi yang berbeda atau berputar. Bagaimana ini bisa dilakukan?

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

Jawaban:


13

Saya ingin melihat apakah saya bisa melakukan ini tanpa secara dinamis meregenerasi mata air untuk setiap frame. Ternyata, ada jalan. : D

Animasi air terjun yang mengalir

Setiap objek yang dapat memblokir air terjun (objek yang memiliki WaterCatcherskrip pada prototipe saya) memiliki garis besar yang melingkari sekelilingnya. (Ini dapat dibuat secara otomatis di muka menggunakan bentuk collider)

Jaring garis besar ini membuat air mengalir di sepanjang objek. Saya menggunakan shader untuk clipmengeluarkan bagian yang berada di bawah objek. Saya juga melacak titik "tangkap" kiri dan kanan di mana air terjun mendarat di objek dan mengalir ke kiri atau kanan masing-masing, sehingga saya dapat clipmengeluarkan bagian yang berada di sebelah kiri air terjun kanan dan di sebelah kanan air terjun kiri.

Animasi menunjukkan jala kulit air

Kemudian jatuh vertikal hanya primitif dasar quad, membentang dengan panjang yang sesuai. Saya menggunakan shader lain untuk menggulir tekstur air terjun di atas air terjun dan memudar di ujung atas & bawah. Lalu saya melapisi sistem partikel busa pada titik tumbukan untuk membantu menutupi campuran.

Ini adalah close-up sehingga Anda dapat melihat bagian-bagian komponen.

Tutup efek air terjun

Di atas saya memiliki air terjun "root" untuk memulai. Setiap frame, setelah semua Update()skrip dijalankan untuk memindahkan benda-benda di sekitarnya, ia menembak CircleCastke bawah, untuk melihat apakah airnya mengenai sesuatu. Jika WaterCatcherkena, ia memberi tahu untuk menunjukkan kulit airnya di hilir titik hit.

Saya menentukan "hilir" menggunakan hit normal - jika itu sangat dekat dengan vertikal, atau jika air terjun yang masuk membentang tepi yang miring di kedua arah, maka kami menumpahkan kiri dan kanan.

Masing-masing WaterCatchermemiliki air terjun kiri dan kanannya sendiri, yang memungkinkan dan posisinya di ujungnya jika tumpah ke arah itu - jika tidak mereka tetap tersembunyi. Air terjun ini pada gilirannya api CircleCastke bawah untuk menemukan apa yang mereka tumpahkan, dan seterusnya ...

Prototipe masih memiliki beberapa gangguan visual yang dapat ditingkatkan - aliran air di sepanjang objek muncul sekaligus daripada menjiwai, dan aturan aliran dapat menggunakan sedikit toleransi ekstra atau histeresis sehingga tidak terputus dengan mudah pada benda berputar. Saya pikir ini harus menjadi masalah yang cukup bisa dipecahkan.

Latar belakang, batu, dan tekstur platform berputar melalui Kenney


Berikut adalah trik yang saya gunakan dalam shader fragmen penangkap air:

// My wraparound geometry is build so the "x+" UV direction
// points "outward" from the object.
// Using derivatives, I can turn this into a vector in screen space.
// We'll use this below to clip out water hanging off the bottom.
float2 outward = float2(ddx(i.uv.x), ddy(i.uv.x));

// i.worldX is the worldspace x position of this fragment
// (interpolated from the vertex shader)

// _LeftX is a material property representing the worldspace x coordinate
// of the rightmost water flow that's spilling left,
// and _RightX the wold x of the leftmost water flow that's spilling right.
float left = _LeftX - i.worldX;   // +ve if we're to the left of a left spill.
float right = i.worldX - _RightX; // +ve if we're to the right of a right spill.

float limit = max(left, right); // +ve if we're in the path of either flow.

// If the "outward" vector is pointing down, make this negative.
limit = min(limit, outward.y + 0.001f);

// If any of the conditions above make limit <= 0, abort this fragment.
clip(limit);

// Otherwise, scroll the water texture!
// Counter-clockwise if we're in the left flow, clockwise otherwise.
i.uv.y -= sign(left) * _Time.y;

Ini bagus. Apakah Anda memiliki rencana untuk menyediakan kode di sini atau di GitHub sehingga komunitas dapat berkontribusi untuk melakukan perbaikan? Jika tidak, silakan pertimbangkan untuk melakukannya.
Kontainment

Tidak ada rencana seperti itu saat ini. Gambar-gambar di atas dibuat dengan bukti konsep cepat & hacky, bukan paket mandiri yang akan cocok untuk penggunaan semacam itu. Beri tahu saya jika Anda membutuhkan tangan untuk mereplikasi semua itu dan saya dapat memandu Anda melalui apa yang dibutuhkan.
DMGregory

Saya sudah bisa membuat partikel busa tetapi saya butuh bantuan membuat shader air dan kedua, memotong shader air di sekitar bentuk (WaterCatcher).
Containment

Saya telah menambahkan potongan kode shader yang menunjukkan cara kerja kliping shader.
DMGregory

@DMGregory WoooW !!! Maaf, sudah lama tidak ke sini. Sedang mengerjakan beberapa hal lainnya. Saya sekarang akan melalui solusi Anda
OnlyCodeMatters

1
  1. Anda dapat mengubah bentuk waterfall mesh pada objek collision agar sesuai dengan pola collider yang diperlukan.

  2. Yang lebih mudah dan lebih akurat, tetapi kinerja yang lebih berat - menggunakan sistem partikel - membuat sistem partikel dengan colliders dan menggunakan setiap partikel sebagai setetes air. Tapi itu terlihat agak aneh jika Anda memiliki sprite default dan jika jumlah partikel kecil dan mereka terlalu besar. Tapi kinerjanya sangat berat, jadi Anda tidak ingin simulasi molekul dalam gim Anda.

Saya akan pergi dengan 1.

  • Tapi CPU deformasi Mesh - lambat, tetapi mungkin bekerja untuk Anda.
  • Saya akan menggunakan shader untuk mencapai ini - Contoh water shader - mesh memiliki efek seperti itu bertabrakan dengan mesh lainnya dan itu jauh lebih cepat daripada metode sebelumnya. Saya kira itu mungkin untuk membuat mesh untuk menghentikan render dalam beberapa bentuk yang diproyeksikan - itu adalah perubahan yang Anda perlukan untuk membuat shader air normal, itu sulit untuk dicapai jika Anda tidak terbiasa dengan shader.

Tidak ada solusi mudah dengan kinerja yang baik.

Hasil dari sistem partikel: (Untuk mengubah nilai saya harus menunggu sekitar 3-4s, ini lambat) Hasil Tabrakan Sistem Partikel


Alternatif untuk poin 1 tetapi mungkin sedikit lebih kompleks adalah memiliki sistem "partikel" Anda sendiri yang menjatuhkan titik / bola bertabrakan dan mematuhi fisika. Dan kemudian "secara sederhana" menghasilkan mesh berdasarkan pada titik-titik itu. cukup banyak cara kerja penyaji baris. Satu-satunya hal yang perlu dipecahkan adalah bagaimana Anda akan membagi poin untuk pergi 2 arah ketika memukul collider seperti di screenshot Anda. Tapi jangan berpikir itu harus sulit. ATAU Anda bisa menempatkan titik secara statis dan menggambar garis di antara mereka. Ya hanya perlu shader yang cantik.
Sidar

@ Sidar Ya, pendekatan yang menarik. Salah satu metode juga akan membuat beberapa penyaji jejak dan memindahkannya dari titik split secara relatif. Dan periksa tabrakan melalui beberapa komponen collider - tapi itu hanya solusinya.
Candid Moon _Max_

Bagaimanapun jika OP tidak ingin mengaturnya secara manual data harus dinamis atau dipanggang secara statis. Saya ingin tahu apakah Anda dapat menggunakan sistem partikel normal dengan tabrakan diaktifkan dan kemudian proximate antara titik untuk menggambar strip quad. Jumlah partikel tidak harus tinggi untuk ini.
Sidar


Bukankah itu per partikel? Saya kira tergantung pada gaya yang Anda tuju yang bisa bekerja dengan baik.
Sidar
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.