Cách tạo thác nước vật lý 2D


8

Tôi đang cố gắng tạo ra một thác nước trông giống với hình ảnh đầu tiên bên dưới (vui lòng kiểm tra video này để biết rõ hơn về những gì tôi muốn đạt được) với các thuộc tính vật lý để nó có thể di chuyển hoặc xung quanh các vật thể có máy va chạm trên nó (tương tự như hình ảnh thứ hai bên dưới). Mặc dù thác nước được liên kết là 3d nhưng tôi quan tâm đến việc thực hiện 2d.

Lưu ý rằng các đối tượng là động và một số di chuyển thường xuyên do đó thác phải định hình lại mọi khung hình. Các đối tượng di chuyển chậm hoặc di chuyển đến các vị trí khác nhau hoặc quay. Điều này có thể giải quyết như thế nào?

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

Câu trả lời:


13

Tôi muốn xem liệu tôi có thể kéo nó ra mà không cần tự động tái tạo lưới cho thác nước mỗi khung hình. Hóa ra, có một cách. : D

Hoạt hình của thác nước

Mỗi đối tượng có thể chặn thác nước (các đối tượng mang WaterCatchertập lệnh trong nguyên mẫu của tôi) có một lưới phác thảo bao quanh chu vi của nó. (Điều này có thể được tạo tự động trước bằng cách sử dụng hình dạng của máy va chạm)

Lưới phác thảo này làm cho nước chảy dọc theo vật thể. Tôi sử dụng một shader để tạo clipra phần bên dưới đối tượng. Tôi cũng theo dõi một điểm "bắt" bên trái và bên phải nơi một thác nước đổ vào vật thể và chảy sang trái hoặc phải tương ứng, vì vậy tôi có thể clipthoát ra phần bên trái của thác nước bên phải và bên phải thác nước bên trái.

Hoạt hình cho thấy lưới nước da

Sau đó, thác thẳng đứng chỉ là tứ nguyên cơ bản, được kéo dài đến độ dài thích hợp. Tôi sử dụng một shader khác để cuộn kết cấu thác nước qua thác và làm mờ nó ở đầu & cuối. Sau đó, tôi lớp trên một hệ thống hạt bọt tại điểm va chạm để giúp che phủ hỗn hợp.

Đây là một cận cảnh để bạn có thể thấy các bộ phận thành phần.

Cận cảnh hiệu ứng thác nước

Ở trên đỉnh tôi có một thác nước "gốc" để khởi động mọi thứ. Mỗi khung hình, sau khi tất cả các Update()tập lệnh đã chạy để di chuyển mọi thứ xung quanh, nó bắn CircleCastxuống phía dưới, để xem liệu nước của nó có chạm vào thứ gì không. Nếu nó chạm a WaterCatcher, nó bảo nó hiển thị vùng nước phía dưới của điểm nhấn.

Tôi xác định "hạ lưu" bằng cách sử dụng cú đánh bình thường - nếu nó rất gần với phương thẳng đứng hoặc nếu thác nước chảy qua các cạnh có độ dốc theo cả hai hướng, thì chúng ta sẽ đổ cả trái và phải.

Mỗi cái WaterCatchercó một thác bên trái và bên phải của riêng nó, nó cho phép và đặt ở vị trí xa của nó nếu nó tràn theo hướng đó - nếu không chúng sẽ bị ẩn. Những thác nước này lần lượt bắn CircleCastxuống để tìm thấy những gì chúng tràn vào, và cứ thế ...

Nguyên mẫu vẫn có một vài trục trặc hình ảnh có thể được cải thiện - dòng nước dọc theo một vật thể bật lên cùng một lúc thay vì hoạt hình, và các quy tắc dòng chảy có thể sử dụng thêm một chút dung sai hoặc độ trễ để nó không bị cắt dễ dàng vật quay. Tôi nghĩ rằng đây là những vấn đề khá giải quyết được mặc dù.

Bối cảnh, đá và kết cấu nền tảng xoay qua Kenney


Dưới đây là các thủ thuật tôi sử dụng trong trình tạo mảnh bắt nước:

// 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;

Điều đó thật tuyệt. Bạn có kế hoạch cung cấp mã nào ở đây hoặc trên GitHub để cộng đồng có thể đóng góp để cải thiện không? Nếu không, hãy xem xét làm như vậy.
Ngăn chặn

Không có kế hoạch như vậy hiện nay. Các hình ảnh trên được tạo ra với một bằng chứng nhanh chóng và khó hiểu về khái niệm, không phải là một gói độc lập phù hợp với loại sử dụng đó. Hãy cho tôi biết nếu bạn cần một bàn tay sao chép bất kỳ thứ gì trong số đó và tôi có thể hướng dẫn bạn những gì cần thiết.
DMGregory

Tôi đã có thể tạo ra các hạt bọt nhưng tôi cần trợ giúp để tạo ra bóng đổ nước và thứ hai, cắt bóng đổ nước xung quanh các hình dạng (WaterCatcher).
Ngăn chặn

Tôi đã thêm một đoạn mã shader cho thấy cách hoạt động của shader shader.
DMGregory

@DMGregory WoooW !!! Xin lỗi, đã không ở đây một thời gian. Đã làm việc trên một số công cụ khác. Bây giờ tôi sẽ xem xét giải pháp của bạn
OnlyCodeMatters

1
  1. Bạn có thể làm biến dạng lưới thác nước trên va chạm đối tượng để phù hợp với mô hình máy va chạm cần thiết.

  2. Một hệ thống hạt dễ sử dụng và chính xác hơn, nhưng hiệu suất cao hơn - tạo ra một hệ thống hạt với máy va chạm và sử dụng mọi hạt như một giọt nước. Nhưng điều đó có vẻ hơi kỳ lạ nếu bạn có sprite mặc định và nếu số hạt nhỏ và chúng quá lớn. Nhưng đó là hiệu suất nặng, vì vậy bạn không muốn mô phỏng phân tử trong trò chơi của mình.

Tôi sẽ đi với 1.

  • Nhưng CPU biến dạng lưới - nó chậm, nhưng có thể phù hợp với bạn.
  • Tôi sẽ sử dụng các shader để đạt được điều này - ví dụ về shader nước - lưới có các hiệu ứng giống như nó va chạm với các mắt lưới khác và nó nhanh hơn các phương pháp trước đây. Tôi đoán rằng có thể tạo lưới để dừng kết xuất trong một số hình dạng được chiếu - đó là thay đổi bạn cần thực hiện đối với trình đổ bóng nước bình thường, sẽ rất khó để đạt được nếu bạn không quen thuộc với trình tạo bóng.

Không có giải pháp dễ dàng với hiệu suất tốt.

Kết quả của hệ thống hạt: (Để thay đổi các giá trị tôi phải đợi khoảng 3-4 giây, nó chậm) Kết quả va chạm hệ thống hạt


Thay thế cho điểm 1 nhưng có thể phức tạp hơn một chút là có hệ thống "hạt" của riêng bạn làm rơi các máy va chạm điểm / hình cầu và tuân theo vật lý. Và sau đó "đơn giản" tạo ra một lưới dựa trên những điểm đó. khá nhiều cách trình kết xuất dòng hoạt động. Điều duy nhất cần được giải quyết là cách bạn chia điểm để đi 2 hướng khi chạm vào máy va chạm giống như trong ảnh chụp màn hình của bạn. Nhưng đừng nghĩ rằng nó cần phải khó. HOẶC bạn chỉ có thể đặt các điểm tĩnh và vẽ một đường thẳng giữa chúng. Ya chỉ cần một shader khá.
Sidar 16/03/18

@Sidar Vâng, cách tiếp cận thú vị. Một trong những phương pháp cũng sẽ là tạo ra nhiều trình kết xuất đường mòn và di chuyển chúng từ điểm phân tách tương đối. Và kiểm tra va chạm thông qua một số thành phần máy va chạm - nhưng đó chỉ là cách giải quyết.
Mặt trăng thí sinh _Max_ 16/03/18

Dù sao đi nữa, nếu OP không muốn thiết lập thủ công, dữ liệu cần phải được động hoặc nướng tĩnh. Tôi tự hỏi nếu bạn có thể sử dụng một hệ thống hạt bình thường với kích hoạt va chạm và sau đó gần giữa các điểm để vẽ một dải tứ giác. Số hạt không phải cao cho việc này.
Sidar 16/03/18


Có phải đó là mỗi hạt tho? Tôi đoán tùy thuộc vào phong cách bạn sẽ làm mà có thể hoạt động khá tốt.
Sidar 16/03/18
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.