Chúng tôi đang xây một hệ thống nước cho Unreal Engine với hai lời hứa: nước trông đúng vì ánh sáng, màu sắc và bọt được tính toán vật lý, không tinh chỉnh tay theo từng cảnh, và nước biết hành xử: thả bất kỳ mesh nào lên bề mặt, nó sẽ nổi, nghiêng hoặc chìm đúng, không cần thiết lập. Đang được phát triển tích cực. Bài này giải thích nó bao gồm gì, chúng tôi tự chịu trách nhiệm bằng ảnh tham chiếu ra sao, vì sao lực nổi là phần khó mà ai cũng bỏ qua, và nó nằm ở đâu bên cạnh phần còn lại của bộ công cụ.
Chuẩn mực cần vượt. Hãy để ý điều gì khiến nó chân thực: bọt sinh ra từ sóng vỡ, sương ăn mòn vách đá, thống kê bọt trắng trên khắp con sóng lừng: không cái nào đặt bằng tay, tất cả là vật lý. Đó là cái xà chúng tôi đã đặt.
Tại sao lại thêm một hệ thống nước?
Hầu hết nước trong game trông tuyệt trong đúng một điều kiện ánh sáng: điều kiện trong ảnh chụp màn hình ở cửa hàng. Dời mặt trời, chuyển sang trời âm u, đặt camera nửa dưới đường nước, và nó rã ra.
Có một thất bại thứ hai, lặng lẽ hơn, quan trọng ngang bằng: gần như mọi hệ thống nước xem các vật thể nổi như một suy nghĩ thêm vào sau. Bạn có một mẫu thuyền, một trang hướng dẫn lắp phao, và giả định ngầm rằng chẳng ai lại ném một cái thùng ngẫu nhiên xuống biển. Người chơi ném thùng xuống biển liên tục.
Chúng tôi muốn hai thứ hiện chưa cùng tồn tại trong một gói: vẻ ngoài chất lượng điện ảnh sống sót qua mọi ánh sáng, và hành xử vật lý không cần thiết lập nào. Không thứ nào đạt được bằng cách vặn tham số cho tới khi một ảnh chụp trông đẹp, vì ảnh chụp là một khung hình dưới một mặt trời, và ngay khi một trong hai thay đổi, nước tinh chỉnh theo khẩu vị lộ ra các đường nối. Nên nền tảng của dự án không phải một danh sách tính năng. Nó là một bài kiểm tra nghiệm thu mà con người không thể cãi lại: một tấm ảnh.
Phán xét trước ảnh, không phải trước khẩu vị
Quá trình phát triển bị chốt bởi các ảnh tham chiếu với hợp đồng camera và ánh sáng cố định: đơn vị ánh sáng vật lý, một tonemapper bị khóa, và một chỉ số khác biệt tri giác quyết định đạt hay không đạt, chứ không phải tâm trạng của giám đốc nghệ thuật ngày hôm đó.
Hai tham chiếu là kinh điển, và được chọn để đối lập nhau:
- Một cái hồ trong, camera ở đường nước. Nửa không khí, nửa nước, một ranh giới gợn sóng không có dải artefact; nước ven bờ ánh lục mà màu sâu dần theo khoảng cách; caustic trên đá khớp với bề mặt phía trên; những khúc gỗ chìm gãy khúc đúng ở mặt phân cách. Cái này kiểm tra khúc xạ, sự vượt qua đường nước và sự hấp thụ màu dưới nước cùng một lúc.
- Một bờ biển bão dưới trời âm u hoàn toàn. Không mặt trời, không dải lấp lánh: biển phải đọc được qua phản chiếu bầu trời mềm mại, xám-lục khử bão hòa, thống kê bọt trắng và sương trên vách đá. Một cái phao cưỡi sóng lừng với chu kỳ và độ nghiêng đáng tin; hành xử là một phần của nghiệm thu, không chỉ hình ảnh tĩnh.
Tham chiếu âm u được chủ ý chọn là một trong hai. Nước dưới nắng nịnh mọi renderer trên Trái Đất, vì lấp lánh specular che giấu vô số tội lỗi. Bỏ mặt trời đi, và nước phải gánh cả khung hình chỉ bằng độ nhám phản chiếu, màu sắc và chuyển động. Đó là bài kiểm tra trung thực, và là bài mà hầu hết hệ thống lặng lẽ né tránh. Một đại dương chỉ đẹp dưới nắng thì không phát hành.
Phía camera được đặc tả nghiêm ngặt như phía nước, vì so sánh ảnh chỉ công bằng khi camera không thể gian lận. Điều đó nghĩa là cường độ ánh sáng vật lý thực (mặt trời giữa trưa quanh 100.000 lux, chứ không phải một thanh trượt độ sáng tùy tiện), phơi sáng cố định, và cấu hình tonemapping và bloom cố định cho từng tham chiếu. Đổi tonemapper thì bất kỳ nước nào cũng có thể làm cho khớp bất kỳ ảnh nào, đó chính xác là lý do tonemapper bị đóng đinh trước tiên.
Drop-a-Mesh: nổi mà không cần làm bài tập
Kéo bất kỳ mesh nào lên một khối nước Numivo và nó hành xử đúng ngay lập tức, vì hệ thống tự dựng một proxy vật lý, tính thể tích chiếm chỗ mỗi khung hình từ chiều cao sóng thực, và suy ra nổi-hay-chìm từ mật độ thực.
Dưới nước là một nơi chốn, không phải một hậu kỳ. Màu hấp thụ theo độ sâu, ánh sáng lọc xuống thành những cột, và mặt phân cách trên đầu phải được vượt qua sạch sẽ: tham chiếu hồ tồn tại để giữ cả ba trung thực cùng lúc.
Một khúc gỗ nổi và lăn sang cạnh dài của nó. Một cái thùng bập bềnh. Một pho tượng đá chìm. Không rig, không đặt phao, không script. Bên dưới nắp capo:
- hình dạng va chạm được voxel hóa tự động (bất đồng bộ, và cache theo asset nên chỉ xảy ra một lần) để đo thể tích thực của vật thể;
- lực nổi được tính vật lý mỗi khung hình từ thể tích chiếm chỗ so với mật độ của nước, và nước ngọt với nước mặn thực sự khác nhau (nước mặn đặc hơn, nên cùng một cái thùng cưỡi cao hơn ở biển so với ở hồ);
- nổi-hay-chìm đến từ mật độ, khối lượng chia cho thể tích proxy: không có ô "cái này có nên nổi không?" làm mặc định, vì mặc định chính là vật lý;
- độ ổn định nảy sinh từ cách thể tích proxy được phân bố: thùng nặng phần trên lật úp, thân tàu dằn ở sống tự đứng thẳng, một tấm ván nằm phẳng;
- vật thể nổi ghép ngược lại vào bề mặt: gợn sóng, vệt sóng, một vòng bọt ở đường nước, và hiệu ứng bắn tóe khi va chạm.
Có một bảng nhỏ trên actor để override (ép nổi, ép chìm, một thanh trượt giảm chấn, công tắc vệt sóng và bắn tóe), nhưng một override co giãn vật lý thay vì thay thế nó. Ép một tảng đá nổi và nó vẫn bập bềnh với chu kỳ đúng và để lại vệt sóng đúng; nó chỉ hành xử như thể nhẹ hơn. Sự phân biệt đó quan trọng: kết quả ép buộc bỏ qua solver trông như những prop dán lên một mặt phẳng, và người chơi nhận ra ngay lập tức.
Mục tiêu thiết kế thẳng thừng, và đó là một demo chúng tôi muốn có thể chạy trực tiếp: ai đó kéo hai mươi prop ngẫu nhiên xuống biển, và mọi thứ cứ thế hành xử, mà không mở trước dù chỉ một cửa sổ thiết lập. Nếu demo đó cần một hướng dẫn, tính năng đã thất bại.
Nó bao gồm gì
Nước ven bờ, đại dương mở, dưới nước và vũng hang đều là hạng nhất: sóng dựa trên phổ với sóng lừng và biển chéo tách biệt, bọt từ những con sóng vỡ thật sự, caustic điều khiển các cột ánh sáng dưới nước, và độ ổn định dưới các hiệu ứng điện ảnh.
Những chi tiết quan trọng nếu bạn quan tâm đến nước:
- Sóng đến từ phổ hải dương học (cùng những mô hình thống kê dùng để mô tả biển thật), với sự lan tỏa theo hướng và sóng lừng điều khiển độc lập. Một trạng thái biển trở thành một quyết định thời tiết, ví dụ "bão đang lên, sóng lừng dài từ hướng tây", thay vì ba mươi thanh trượt rời rạc mà bạn đẩy cho tới khi trông có vẻ bão.
- Bọt không phải một mask vẽ tay. Nó sinh ra nơi sóng thật sự vỡ, già đi theo thời gian, và vệt dài dưới gió. Bọt vẽ là dấu hiệu phổ biến nhất của nước giả, vì nó không chuyển động cùng vật lý mà nó đáng lẽ đại diện.
- Dưới nước là một nơi chốn thật. Hấp thụ màu đúng theo độ sâu (đỏ đi trước, rồi lục, để lại màu xanh sâu ai cũng biết từ thước phim lặn), các cột ánh sáng suy ra từ chính trường caustic thắp sáng đáy, và một sự vượt qua ở đường nước mà không có dải artefact cứng kinh điển.
- Vũng hang được xử lý riêng (nước tĩnh hay hầu như không động, nhiễu động từ giọt nước, phản chiếu trong gần như bóng tối), vì một vũng nội thất tĩnh lặng phơi bày những thất bại khác với đại dương mở.
- Cinematic là tiêu chí nghiệm thu, không phải suy nghĩ thêm. Bề mặt phải giữ ổn định dưới độ sâu trường ảnh, motion blur và hạt phim: không có fireflies specular chỉ xuất hiện khi áp hạt, không có lấp lánh mà một camera chậm biến thành strobing.
Vì sao lực nổi là phần ai cũng bỏ qua
Vẻ ngoài có thể giả bằng một shader tốt, nhưng hành xử thì không: một nổi-và-chìm thuyết phục cần một ước lượng thể tích thời gian thực và một solver ổn định, điều thật sự khó, nên hầu hết hệ thống phát một prefab thuyền rồi dừng.
Sự thật kỹ thuật khó chịu là một shader nước đẹp là một bài toán đã giải, còn một solver lực nổi tổng quát thì không. Giả vẻ ngoài của một con sóng là bài toán texture-và-normal; làm cho một mesh tùy ý, chưa từng thấy trước đó, ngồi đúng trong con sóng ấy là một bài toán vật lý phải chạy ở tốc độ khung hình, sống sót qua các bước thời gian nhanh, và không nổ tung khi một tảng đá nghìn tam giác gặp sóng lừng bão. Khoảng cách đó là lý do "nước" trong hầu hết engine nghĩa là "một mặt phẳng đẹp mà bạn không thể tương tác", và vì sao phần tương tác, khi tồn tại, là một con thuyền làm bằng tay.
Khép lại khoảng cách đó, làm hành xử tự động như vẻ ngoài, là lý do dự án này tồn tại và lý do nó cần kỷ luật ảnh-tham-chiếu cộng một solver thật, chứ không phải một cuối tuần làm shader.
Khi nào bạn dùng được?
Nó đang được phát triển như một extension của Unreal Engine, với một triển khai theo giai đoạn: một bản xem trước nổi kiểu động học hạ cánh trước solver vật lý đầy đủ, nên cảnh có thể được lấp đầy sớm. Chúng tôi không công bố ngày; các ảnh tham chiếu quyết định khi nào xong.
Việc chia giai đoạn là chủ ý. Một bản xem trước động học (vật thể bám theo bề mặt sóng mà không mô phỏng lực đầy đủ) đến trước, để nghệ sĩ có thể thả mesh và lấp đầy một vùng biển trong khi solver nặng vẫn đang được tôi luyện: bạn cảm nhận kết quả từ rất lâu trước khi vật lý hoàn chỉnh. Solver đầy đủ, auto-proxy và bảng điều khiển hoàn chỉnh theo sau. Tiến độ và các cột mốc xuất hiện trên lộ trình công khai, không phải trong một bất ngờ ngày ra mắt.
Bộ công cụ mà nó sẽ phát hành cùng (scatter, mesh blending, grid, đo đạc) miễn phí dùng thử hôm nay. Nếu bạn muốn được thông báo ngay khi có một bản build nước công khai, Discord được liên kết từ trang web là nơi nó sẽ được công bố đầu tiên, và là nơi các so sánh đạt/không đạt của ảnh tham chiếu sẽ được đăng khi chúng diễn ra.
Mini-FAQ
Nó có đòi hỏi các công cụ khác của Numivo không? Không, nó là một extension trong cùng gia đình, thiết kế để đứng một mình. Tuy vậy nó chia sẻ cùng nguyên tắc: kết quả bake thành dữ liệu engine-native ở bất cứ đâu khả thi về mặt vật lý, để bạn sở hữu những gì bạn làm.
Phiên bản engine nào? Các bản phát hành Unreal Engine 5 hiện tại. Chi tiết hạ cánh lên lộ trình khi extension tiến gần một bản build công khai, thay vì được hứa bây giờ rồi sửa sau.
Nó khác gì với nước có sẵn của engine? Các hệ thống nước có sẵn mạnh về vẻ ngoài và yếu về tương tác tổng quát: lực nổi thường là một thành phần riêng, tinh chỉnh tay. Toàn bộ điểm ở đây là vẻ ngoài và hành xử đến từ một hệ thống duy nhất có nền tảng vật lý, với cánh cửa ảnh-tham-chiếu giữ vẻ ngoài trung thực qua các ánh sáng.
Vì sao công bố trước khi phát hành? Vì bản thân phương pháp ảnh tham chiếu chính là điểm cốt lõi. Chúng tôi thà trưng cái xà ra công khai và để bị đo bằng nó, còn hơn hé lộ một thứ đã xong mà không ai soi xét được. Bài viết này chính là cái xà đó, bằng chữ, nên hãy bắt chúng tôi giữ lời.