Nghệ thuật Dithering và Phong cách Retro cho Web: Khi Shader Đưa Bạn Về Thập Niên 90

Công nghệ13 tháng 10, 2026·6 phút đọc

Dithering từng là giải pháp kỹ thuật để bù đắp khả năng hiển thị màu hạn chế của máy tính thời kỳ đầu, nay đã trở thành lựa chọn nghệ thuật đầy cảm hứng cho các lập trình viên WebGL. Bài viết phân tích cách xây dựng hiệu ứng hậu kỳ (post-processing) retro trong React Three Fiber, từ nhiễu trắng, dithering có trật tự, lượng tử hóa màu cho đến hiệu ứng màn hình CRT.

Nghệ thuật Dithering và Phong cách Retro cho Web: Khi Shader Đưa Bạn Về Thập Niên 90

Nghệ thuật Dithering và Phong cách Retro cho Web: Khi Shader Đưa Bạn Về Thập Niên 90

Tác giả Maxime Heckel đã dành nhiều tháng xây dựng lại trang web cá nhân từ con số không, kết hợp các kỹ thuật 3D để thể hiện khả năng shader và WebGL của mình. Trong quá trình đó, anh nhận ra vai trò then chốt của hậu kỳ (post-processing) — thứ mà trước đây anh từng loay hoay mà không đạt được kết quả như mong muốn với React Three Fiber.

Bài viết dưới đây tổng hợp những kiến thức nền tảng và kỹ thuật shader đằng sau các hiệu ứng retro, từ dithering, lượng tử hóa màu cho đến pixel hóa và hiệu ứng màn hình CRT.

Dithering là gì và tại sao nó quay trở lại?

Dithering ra đời như một thủ thuật đồ họa thời kỳ đầu: bằng cách cố tình thêm nhiễu (noise) lên hình ảnh hoặc khung hình render, người ta đánh lừa não bộ người xem để họ cảm nhận được nhiều màu sắc hơn hoặc các dải chuyển màu (gradient) mượt mà hơn so với khả năng thực tế của máy.

Bảng màu thời đó rất hạn chế, nên kỹ thuật này là yếu tố sống còn để các nhà thiết kế game hiện thực hóa ý tưởng. Nhờ vậy, các tựa game và nội dung đa phương tiện giai đoạn máy tính trở nên phổ biến nhưng năng lực đồ họa còn yếu đã có một phong cách rất riêng.

Ví dụ về dithering trong đồ họaVí dụ về dithering trong đồ họa

Ngày nay, dithering không còn là giải pháp chữa cháy mà đã trở thành lựa chọn nghệ thuật. Nhiều nghệ sĩ và nhà thiết kế game dùng nó để tạo cảm giác hoài niệm, gợi nhớ thời kỳ game sơ khai, hoặc để tự giới hạn bảng màu một cách có chủ đích. Một vài ví dụ tiêu biểu:

  • Trò chơi point-and-click Basement Chronicle của Basement Studio — một tác phẩm chỉn chu gợi lại trải nghiệm chơi game thuở ban đầu.
  • Các tác phẩm của nghệ sĩ @loackme.
  • Thử nghiệm nhiếp ảnh của @aweusmeuh với camera Game Boy nguyên bản, mang đến hiệu ứng dithering tuyệt đẹp.

Bước đầu triển khai dithering trong React Three Fiber

Để tạo hiệu ứng tùy chỉnh, ta sẽ mở rộng lớp Effect của thư viện postprocessing, khai báo fragment shader và truyền vào hàm khởi tạo cha thông qua từ khóa super. Sau đó, dùng hàm wrapEffect từ @react-three/postprocessing để biến lớp này thành một component JSX dùng được trong EffectComposer.

Ý tưởng của phiên bản đầu tiên — dithering nhiễu trắng (white noise dithering) — rất đơn giản:

  1. Xem xét độ sáng (luminance) của từng pixel.
  2. So sánh với một số ngẫu nhiên — đây chính là "nhiễu trắng".
  3. Xuất ra pixel trắng hoặc đen tùy theo độ sáng nằm trên hay dưới con số ngẫu nhiên đó.

Cách này nhanh nhưng thô, và như ta sẽ thấy, có những kỹ thuật tinh tế hơn nhiều để tạo ra các mẫu pixel đẹp mắt.

Ma trận Bayer và dithering có trật tự

Dithering có trật tự (ordered dithering) sử dụng một ma trận ngưỡng có cấu trúc — nổi tiếng nhất là ma trận Bayer — thay vì nhiễu ngẫu nhiên. Kết quả là các mẫu pixel lặp lại có tổ chức, giúp bảo toàn chi tiết hình ảnh tốt hơn hẳn so với nhiễu trắng, đồng thời tạo ra vẻ ngoài rất đặc trưng của đồ họa retro.

Ma trận Bayer dùng cho dithering có trật tựMa trận Bayer dùng cho dithering có trật tự

Các bước cốt lõi của quy trình gồm:

  • Chuyển sang thang độ xám (grayscale) để xác định độ sáng từng pixel.
  • Lượng tử hóa màu (color quantization): giảm số lượng màu xuống một bảng giới hạn — ví dụ 2 màu, 4 màu.
  • Áp dụng ma trận Bayer để quyết định pixel nào giữ màu nào, tạo cảm giác chuyển sắc mượt dù bảng màu rất hẹp.

Ảnh gốc chuyển sang thang độ xámẢnh gốc chuyển sang thang độ xám

Việc chuyển bảng màu từ 2 màu sang 4 màu cho thấy rõ sự đánh đổi giữa tính "retro thuần túy" và mức độ chi tiết hiển thị. Bảng màu càng ít, phong cách càng cổ điển nhưng càng mất chi tiết; bảng màu nhiều hơn thì cân bằng hơn nhưng kém "chất" retro.

Hiệu ứng màn hình CRT: pixel hóa, nhiễu RGB và cong màn hình

Phần thú vị nhất của dự án là mô phỏng lại cảm giác của màn hình CRT thời xưa. Các kỹ thuật bao gồm:

Pixel hóa và lưới RGB (RGB cell shadow mask): mô phỏng quá trình lấy mẫu xuống (downsampling) đặc trưng của màn hình CRT cũ, nơi mỗi pixel thực chất là một cụm ba ô màu đỏ — xanh lá — xanh dương.

Đường quét ngang (scanlines): chồng lên kết quả đầu ra bằng một hàm sin chạy dọc theo trục tung, kết hợp với thời gian để tạo hiệu ứng nhấp nháy nhẹ như màn hình cũ đang hoạt động.

Biến dạng UV (distortion): thêm nhiễu Perlin vào tọa độ UV trong hàm mainUv để tạo rung lắc nhẹ, khiến hình ảnh trông chân thực hơn — giống như tín hiệu analog bị nhiễu.

Cong màn hình, bloom và quang sai màu (chromatic aberration): những lớp hoàn thiện cuối cùng giúp hiệu ứng thực sự "nổi bật" và đáng tin.

Sự kết hợp giữa lượng tử hóa màu, dithering có trật tự và hiệu ứng CRT tạo nên một sự tương phản thú vị giữa nền web hiện đại và một thời kỳ công nghệ đã qua — thứ mà thế hệ lớn lên cùng thập niên 90 và đầu 2000 vẫn luôn hoài niệm.

Điều gì khiến kỹ thuật này đáng học?

Điểm mấu chốt mà tác giả muốn nhấn mạnh là sức mạnh của hiệu ứng hậu kỳ tùy chỉnh. Chúng cho phép bạn áp một shader lên một cảnh 3D đã render xong, thay đổi phong cách giống như gắn bộ lọc ảnh lên một bức ảnh — mà không cần đụng đến hình học hay vật liệu gốc.

Các khối kỹ thuật riêng lẻ — dithering, lượng tử hóa màu, pixel hóa, RGB cell — đều có thể dùng độc lập và tinh chỉnh vô hạn. Với các lập trình viên web Việt Nam đang tìm cách tạo dấu ấn riêng trong lĩnh vực nghệ thuật số và web 3D, đây là hướng đi đáng cân nhắc: chi phí thấp, hiệu quả thị giác cao, và tạo được sự khác biệt giữa vô số trang web na ná nhau.

Công cụ thì đã có sẵn, kỹ thuật đã được chia sẻ đầy đủ — phần còn lại là thử nghiệm và sáng tạo của chính bạn.

Chia sẻ:FacebookX
Nội dung tổng hợp bằng AI, mang tính tham khảo. Xem bài gốc ↗