Kỹ thuật lập trình Shader: Tái hiện bầu trời, hoàng hôn và khí quyển hành tinh
Bài viết này đi sâu vào quy trình kỹ thuật phức tạp để tái hiện các hiệu ứng khí quyển thực tế như bầu trời xanh, hoàng hôn và vỏ khí quyển của hành tinh bằng cách sử dụng shader. Tác giả chia sẻ từng bước từ lý thuyết tán xạ Rayleigh và Mie, kỹ thuật raymarching cho đến các phương pháp tối ưu hóa hiệu suất bằng bảng tra cứu (LUT) để chạy trực tiếp trên trình duyệt.

Có một bức ảnh về tàu con thoi Endeavour lơ lửng trong quỹ đạo Trái Đất vào lúc hoàng hôn đã truyền cảm hứng mạnh mẽ cho nhiều lập trình viên đồ họa. Bức ảnh này không chỉ đẹp về mặt thẩm mỹ với các lớp màu từ cam đậm đến xanh dương trước khi hòa vào đen kịt của vũ trụ, mà còn gợi mở về hiện tượng vật lý phức tạp đằng sau nó: tán xạ khí quyển.
Tàu con thoi Endeavour trong hoàng hôn
Là một người làm việc trong lĩnh vực đồ họa máy tính, tôi đã dành một tháng để nghiên cứu và xây dựng lại hiệu ứng này bằng shader. Mục tiêu là tái hiện màu xanh đặc trưng của bầu trời, những buổi bình minh/hoàng hôn thực tế và áp dụng chúng vào quy mô một hành tinh, tất cả chạy thời gian thực (real-time) ngay trên trình duyệt.
Cơ chế vật lý của bầu trời
Để bầu trời trông thật chứ không chỉ là một gradient màu xanh đơn giản, chúng ta cần mô phỏng sự tương tác của ánh sáng với không khí và các thành phần của nó. Điều này liên quan đến hai loại tán xạ chính:
- Tán xạ Rayleigh (Rayleigh Scattering): Xảy ra khi ánh sáng tương tác với các hạt nhỏ hơn nhiều so với bước sóng ánh sáng (như phân tử nitơ và oxy). Hiện tượng này giải thích tại sao bầu trời lại có màu xanh vào ban ngày (ánh sáng xanh bị tán xạ mạnh hơn) và màu đỏ khi hoàng hôn (ánh sáng phải đi qua lớp khí quyển dày hơn).
- Tán xạ Mie (Mie Scattering): Mô tả sự tương tác của ánh sáng với các hạt lớn hơn như bụi hoặc aerosol. Loại tán xạ này tạo ra vầng hào quang trắng xung quanh mặt trời và làm giảm độ tương phản của bầu trời.
Ngoài ra, chúng ta cũng cần tính đến hấp thụ Ozone, nơi tầng ozone hấp thụ một phần ánh sáng đi qua tầng cao của khí quyển, làm sâu hơn màu sắc của bầu trời, đặc biệt là gần đường chân trời.
Kỹ thuật Raymarching và tính toán ánh sáng
Để mô phỏng thể tích (volume) của khí quyển, chúng ta sử dụng kỹ thuật Raymarching. Thay vì tính toán cho mỗi điểm ảnh một cách đơn giản, chúng ta bắn các tia từ camera vào cảnh và bước qua môi trường trong suốt để trả lời hai câu hỏi:
- Có bao nhiêu ánh sáng sống sót sau khi đi qua khí quyển? (Độ truyền thấu - Transmittance).
- Có bao nhiêu ánh sáng bị chuyển hướng về phía camera tại mỗi mẫu? (Tán xạ - Scattering).
Chúng ta sử dụng Định luật Beer để tính toán độ truyền thấu dựa trên độ sâu quang học (optical depth) tích lũy dọc theo tia. Tuy nhiên, chỉ tính toán độ truyền thấu từ camera là chưa đủ. Để có hiệu ứng hoàng hôn chính xác, chúng ta cần một vòng lặp lồng nhau (lightmarching) để tính toán lượng ánh sáng mặt trời bị mất khi đi qua khí quyển trước khi đến điểm mẫu đó.
Kết xuất hành tinh và thách thức về độ sâu
Khi áp dụng shader này cho quy mô hành tinh, chúng ta gặp phải vấn đề về độ chính xác của bộ đệm độ sâu (depth buffer). Do khí quyển rất mỏng so với bán kính hành tinh, việc phân biệt độ sâu giữa bề mặt hành tinh và lớp khí quyển từ xa là rất khó.
Giải pháp là chuyển sang Logarithmic Depth Buffer (Bộ đệm độ sâu logarithmic). Điều này cho phép chúng ta xử lý các khoảng cách lớn hơn nhiều mà không bị hiện tượng "depth fighting" (nhiều bề mặt cạnh tranh nhau cùng một pixel).
Chúng ta cũng sử dụng phép kiểm tra giao nhau giữa tia và hình cầu (ray-sphere intersection) để xác định chính xác nơi khí quyển bắt đầu và kết thúc, cũng như nơi tia va chạm với bề mặt hành tinh.
So sánh hiệu ứng tán xạ Mie
Tối ưu hóa hiệu suất với Look Up Tables (LUT)
Shader ban đầu hoạt động tốt nhưng rất tốn tài nguyên vì phải thực hiện tính toán raymarching và lightmarching cho mỗi pixel ở độ phân giải đầy đủ. Để tối ưu hóa, tôi đã áp dụng phương pháp của Sebastian Hillaire sử dụng các Bảng tra cứu (Look Up Tables - LUTs):
- Transmittance LUT: Lưu trữ lượng ánh sáng sống sót khi đi qua khí quyển cho các độ cao và góc nhìn mặt trời khác nhau.
- Sky-view LUT: Lưu trữ màu của bầu trời cho một vị trí camera và hướng nhìn cụ thể.
- Aerial Perspective LUT: Lưu trữ sương mù/khí quyển giữa camera và các vật thể trong cảnh.
Thay vì tính toán lại các hàm toán học phức tạp, shader cuối cùng chỉ cần lấy mẫu (sample) từ các texture đã được tính toán trước này. Điều này giúp thay thế một vòng lặp lồng nhau tốn kém bằng một tra cứu texture đơn giản, mang lại hiệu suất đáng kể.
Kết luận
Dự án này là một hành trình thú vị từ vật lý cơ bản đến tối ưu hóa đồ họa hiện đại. Việc tái hiện bầu trời và hành tinh không chỉ đòi hỏi kiến thức toán học mà còn cả sự tinh tế trong việc điều chỉnh các thông số shader. Mặc dù phương pháp LUT đã cải thiện hiệu suất, tôi vẫn hy vọng có thể áp dụng WebGPU và Compute Shaders trong tương lai để đẩy mạnh hơn nữa khả năng kết xuất đồ họa thời gian thực trên trình duyệt.
Bài viết liên quan

Công nghệ
Cerebras, đối tác thân thiết của OpenAI, sẵn sàng cho đợt IPO kỷ lục định giá tới 26,6 tỷ USD
04 tháng 5, 2026

Công nghệ
Microsoft giới thiệu Surface Pro 12 và Surface Laptop 8: Sức mạnh chip Intel, giá thành gây sốc
19 tháng 5, 2026

Công nghệ
Substrate (YC S24) tuyển dụng Technical Success Manager cho nền tảng AI chuyên xử lý thanh toán y tế
13 tháng 5, 2026
