Saya ingin melihat apakah saya bisa melakukan ini tanpa secara dinamis meregenerasi mata air untuk setiap frame. Ternyata, ada jalan. : D
Setiap objek yang dapat memblokir air terjun (objek yang memiliki WaterCatcher
skrip 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 clip
mengeluarkan 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 clip
mengeluarkan bagian yang berada di sebelah kiri air terjun kanan dan di sebelah kanan air terjun kiri.
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.
Di atas saya memiliki air terjun "root" untuk memulai. Setiap frame, setelah semua Update()
skrip dijalankan untuk memindahkan benda-benda di sekitarnya, ia menembak CircleCast
ke bawah, untuk melihat apakah airnya mengenai sesuatu. Jika WaterCatcher
kena, 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 WaterCatcher
memiliki 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 CircleCast
ke 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;