Nghệ thuật dựng bầu trời đẹp trong game Around The World
Nhà phát triển Thomas ten Cate chia sẻ quá trình tinh chỉnh bầu trời trong game khám phá đại dương Around The World, từ việc tự viết ray tracer để sửa lỗi tán xạ ánh sáng đa lớp trong mây cho đến mẹo uốn cong đường chân trời và tinh chỉnh tone mapping. Bài viết hé lộ nhiều thủ thuật đồ họa thú vị mà bất kỳ lập trình viên game nào cũng có thể học hỏi.

Nghệ thuật dựng bầu trời đẹp trong game Around The World
Trong loạt bài về quá trình phát triển Around The World — một tựa game khám phá và phiêu lưu trên biển — nhà phát triển Thomas ten Cate đã dành hẳn một bài viết để kể lại hành trình làm cho bầu trời trở nên "đẹp" hơn. Từ việc nghi ngờ công cụ dựng hình povray không mô phỏng đúng tán xạ ánh sáng đa lớp, đến những mẹo nhỏ bất ngờ giúp mây hòa quyện vào bầu trời, đây là câu chuyện thú vị về sự giao thoa giữa vật lý, toán học và kỹ thuật đồ họa máy tính.
Khi niềm tin vào povray lung lay
Bài viết trước kết thúc với một bảng tra cứu (LUT) do povray kết xuất, thể hiện lượng ánh sáng tán xạ khỏi mây tùy theo góc chiếu của ánh sáng và mật độ mây. Tuy nhiên, tác giả nhận thấy phần đáy của các khối cầu mây không hề sáng lên dù đã tăng mạnh số mẫu và số bước tích phân.
Để kiểm chứng, ông quyết định viết một ray tracer Monte Carlo đệ quy đa luồng bằng Rust chỉ trong vài trăm dòng code. Công cụ này cực kỳ đơn giản và gắn cứng với tình huống cụ thể, nhưng đủ để chứng minh rằng povray thực sự không mô phỏng tán xạ đa lớp (multiple scattering). Kết quả cho ra một bảng tra cứu hoàn toàn khác: ánh sáng phân bố đều hơn nhiều, khiến mây trông sáng và mềm mại hơn hẳn.
Bảng tra cứu cũ từ povray
Với mây mỏng, khác biệt không đáng kể vì ánh sáng gần như không có cơ hội bị tán xạ nhiều hơn một lần. Nhưng với lớp mây dày hơn, sự khác biệt hiện rõ rệt.
Hiệu ứng "kim loại" biến mất
So sánh trực tiếp trên hình ảnh cho thấy kết quả rõ ràng. Đây là mây dựng bằng bảng tra cứu cũ:
Mây dựng bằng bảng tra cứu cũ, trông kim loại
Và đây là mây với bảng tra cứu mới:
Mây với bảng tra cứu mới, đáy sáng và mềm hơn
Cảm giác "kim loại" mà tác giả từng phàn nàn đã biến mất hoàn toàn. Đáy mây sáng hơn, ánh sáng mượt mà và tự nhiên hơn nhiều.
Mẹo nhỏ với vector pháp tuyến
Một vấn đề khác: mây trong thực tế không chỉ được chiếu sáng bởi mặt trời trực tiếp mà còn nhận ánh sáng gián tiếp từ bầu trời — vốn thường có sắc xanh. Tác giả không muốn thêm một hằng số "xanh" cố định vì điều đó chỉ đúng vào ban ngày; mây cần phản ánh màu bầu trời hiện tại, kể cả lúc bình minh, hoàng hôn hay ban đêm.
Giải pháp nằm ở cách Godot xử lý ánh sáng gián tiếp (indirect light). Với vật liệu khuếch tán như mây, engine lấy mẫu cube map theo hướng của vector pháp tuyến bề mặt. Ở đáy mây, pháp tuyến hướng xuống đất nên mây rất ít nhận ánh sáng gián tiếp. Nhưng nếu xoay pháp tuyến hướng lên trời, hiệu ứng sẽ khác hẳn.
Kết quả thật bất ngờ: mây có thêm sắc xanh, hòa quyện với bầu trời tốt hơn, trông mềm mại và xa xăm đúng chất mây thật. Vào lúc hoàng hôn, khi ánh sáng trực tiếp có màu cam, mây chuyển sang sắc hồng — đúng với vẻ đẹp của những buổi chiều tà ngoài đời, khi ánh sáng đỏ trực tiếp hòa với ánh sáng xanh gián tiếp.
Tán xạ khí quyển và đường chân trời
Tác giả cũng khó chịu vì bầu trời ngả vàng bất thường gần đường chân trời, ngay cả khi mặt trời đứng giữa đỉnh đầu. Ông thử nhiều hướng khắc phục và cuối cùng phát hiện ra rằng chỉ cần đảo thứ tự các phép toán trong quá trình ray march — giảm cường độ ánh sáng do outscattering trước, rồi mới cộng ánh sáng inscattering — kết quả đã đẹp hơn hẳn.
Vấn đề tiếp theo là uốn cong đường chân trời. Game sử dụng tham số khí quyển của Trái Đất thật, nhưng hành tinh trong game nhỏ hơn khoảng 75 lần nên cong mạnh hơn nhiều. Kết quả là đường chân trời của bầu trời nằm cao hơn đường chân trời thực, tạo ra một dải tối khó coi, đặc biệt rõ vào lúc bình minh và hoàng hôn.
Cách xử lý rất đơn giản: cộng một giá trị nhỏ vào thành phần y của vector hướng nhìn toàn cục, rồi chuẩn hóa lại. Hiệu ứng là kéo toàn bộ bầu trời xuống, mạnh nhất ở gần đường chân trời, khiến dải tối biến mất sau đường chân trời thật. Một mẹo thô nhưng rẻ và hiệu quả.
Đường chân trời sau khi uốn cong bằng mẹo nhỏ
Tone mapping — nỗi khổ của nghệ sĩ 3D
Game hiện đại kết xuất ở dải động cao (HDR), nên các giá trị màu có thể vượt quá 1.0. Hiển thị trực tiếp trên màn hình thông thường sẽ gây cháy màu. Godot cung cấp nhiều bộ tone mapper, nhưng tác giả thấy Reinhard quá tối, còn ACES và AgX lại bạc màu quá mức. Cuối cùng, ông chọn Filmic với điểm trắng 2.0, giúp mây có vẻ mềm mại và tan dần vào khoảng không tốt hơn.
Tác giả thừa nhận đây là quá trình lặp đi lặp lại đầy khó khăn, vì thay đổi tone mapper ảnh hưởng đến mọi thứ đã chỉnh trước đó. Có lúc ông phải giảm độ sáng bầu trời xuống một nửa để đạt độ tương phản tốt hơn sau khi tone mapping.
Mô hình hệ mặt trời để tính bình minh
Để có chu kỳ ngày đêm chân thực — mặt trời mọc và lặn phụ thuộc vào vị trí địa lý và mùa — tác giả chọn cách đơn giản hơn việc giải toàn bộ bài toán thiên văn: dựng hẳn một mô hình hệ mặt trời (orrery) trong engine, cho hành tinh và mặt trăng quay như thật, rồi để engine tự tính phép biến đổi ngược để xác định vị trí các thiên thể trên bầu trời từ góc nhìn của người quan sát. Cách làm này không chỉ hoạt động tốt mà còn trở thành công cụ gỡ lỗi hữu ích.
Bài viết là một minh chứng đẹp cho việc đôi khi giải pháp tốt nhất không phải là công thức toán học phức tạp, mà là tận dụng chính engine — và đôi khi chỉ cần một mẹo nhỏ đúng chỗ.
Với độc giả Việt Nam quan tâm đến lập trình game, đặc biệt là những ai đang làm việc với Godot — một engine mã nguồn mở ngày càng phổ biến trong cộng đồng — bài viết này là nguồn tham khảo thực tế về cách xử lý ánh sáng, khí quyển và hậu kỳ hình ảnh. Toàn bộ chuỗi bài về Around The World có thể được theo dõi trên blog cá nhân của tác giả.

