Vì Sao Mô Hình 3D Lại Nặng Đến Vậy?
Tệp GLB của bạn chỉ nặng 10MB, nhưng khi mở trên điện thoại lại ngốn tới 200MB VRAM và làm sập ứng dụng. Hãy cùng mổ xẻ sự thật đằng sau hiện tượng này.
Mô Hình Của Bạn Đang Âm Thầm Tăng Cân
Bạn xuất một tệp mô hình GLB. Dung lượng chỉ 10MB, cảm giác rất nhẹ nhàng. Bạn tải tệp lên điện thoại, mở ra xem: màn hình trắng xóa, giật lag dữ dội và cuối cùng là ứng dụng bị sập hoàn toàn.
Mọi thứ chạy rất mượt mà trên máy tính để bàn, nhưng lại nổ tung trên thiết bị di động. Vấn đề không nằm ở mã nguồn của bạn. Các mô hình 3D mang một đặc tính phi trực giác: kích thước tệp lưu trên ổ đĩa khác hoàn toàn dung lượng chiếm dụng trong bộ nhớ đồ họa VRAM.
Một bức ảnh JPEG trên ổ cứng có thể chỉ nặng 200KB. Nhưng GPU hoàn toàn không hiểu định dạng JPEG, nó chỉ biết xử lý các điểm ảnh thô không nén. Vì vậy, trước khi được đẩy lên VRAM, bức ảnh đó bắt buộc phải được giải nén toàn bộ. Một bức ảnh kết cấu 2048×2048 sau khi bung ra sẽ ngốn khoảng 22MB VRAM. Nếu bạn dùng đủ sáu bản đồ kết cấu (màu albedo, pháp tuyến normal, độ nhám roughness, kim loại metallic, bóng đổ AO, phát sáng emissive), chỉ riêng một vật liệu đã ngốn đứt 132MB bộ nhớ đồ họa.
Một chiếc điện thoại phổ thông có thể chỉ có từ 2 đến 4GB bộ nhớ VRAM dùng chung. Các bức ảnh của duy nhất một mô hình đã nuốt chửng 3-6% con số đó. Vậy chuyện gì sẽ xảy ra nếu cảnh 3D của bạn chứa 10 mô hình cùng lúc?
Bóc Tách Chi Tiết: Dung Lượng Đã Đi Về Đâu?
Một mô hình GLB tiêu chuẩn được tạo nên từ ba thành phần chính: dữ liệu đỉnh, bản đồ kết cấu, cùng với siêu dữ liệu và hoạt cảnh chuyển động.
Xét một mô hình PBR trong thực tế:
| Thành phần cấu tạo | Chi tiết bên trong | Tỷ lệ điển hình | Ghi chú quan trọng |
|---|---|---|---|
| Bản đồ kết cấu | albedo, normal, roughness, metallic, AO... | 70 đến 85% | Luôn là thành phần nặng nhất |
| Dữ liệu đỉnh lưới | vị trí position, pháp tuyến normal, UV, tiếp tuyến tangent, màu đỉnh | 10 đến 20% | Phụ thuộc vào độ phức tạp hình học |
| Hoạt cảnh chuyển động | xương khớp, trọng số da skinning, khung hình khóa | 0 đến 15% | Chỉ có khi mô hình có animation |
| Dữ liệu khác | định nghĩa vật liệu, cấu trúc cây phân cấp, camera | Dưới 2% | Chiếm lượng không đáng kể |
Các bản đồ kết cấu chiếm tới 80% dung lượng tệp. Bạn thường lầm tưởng rằng mình cần tập trung tối ưu đỉnh lưới, nhưng thủ phạm thực sự ngốn tài nguyên lại là các bức ảnh kết cấu.

"Nhỏ Trên Ổ Đĩa" Không Có Nghĩa Là "Nhẹ Trong VRAM"
Đây có lẽ là khái niệm kỹ thuật cốt lõi và quan trọng nhất để làm chủ hiệu năng đồ họa 3D.
PNG và JPEG được sinh ra để truyền tải trên mạng: dung lượng tệp nhỏ, tải về nhanh chóng. Nhưng phần cứng GPU không thể trực tiếp đọc chúng; chúng bắt buộc phải được giải nén toàn bộ thành các mảng điểm ảnh thô. Công thức tính toán như sau:
Chiếm dụng VRAM = Chiều rộng * Chiều cao * 4 byte (RGBA) * 1.333 (kèm mipmaps)
Một bức ảnh RGBA kích thước 4096×4096:
| Chỉ số đo lường | Giá trị thực tế |
|---|---|
| Dung lượng tệp PNG | ~8MB |
| Dung lượng tệp JPEG | ~1.5MB |
| Chiếm dụng VRAM (kèm mipmaps) | ~87MB |
Một bức ảnh JPEG chỉ 1.5MB biến thành một khối nặng 87MB khi nằm trong VRAM.
Mipmap là gì? Phần cứng GPU tự động sinh ra một chuỗi các phiên bản thu nhỏ dần của bức ảnh: từ kích thước gốc cho đến mức 1×1 điểm ảnh, mỗi cấp độ giảm một nửa so với cấp trước. Cơ chế này giúp các vật thể ở xa hiển thị sạch sẽ, không bị răng cưa nhấp nháy, nhưng nó tiêu tốn thêm khoảng 33% dung lượng VRAM. Hầu như mọi ứng dụng 3D đều bắt buộc dùng mipmap, nên phần chi phí bộ nhớ này là tiêu chuẩn.
Vì vậy ảnh PNG/JPEG giống như túi hút chân không khi đóng gói hành lý du lịch: gấp lại thì rất gọn gàng khi mang đi, nhưng khi tới nơi bạn bắt buộc phải bơm phồng mọi thứ trở lại kích thước thật. Tốc độ tải về có thể nhanh, nhưng không hề tiết kiệm được chút bộ nhớ đồ họa VRAM nào.

Hậu Quả Khi Tràn Bộ Nhớ VRAM
Trình duyệt sẽ không hiện ra một hộp thoại lịch sự nhắc nhở "Đã hết bộ nhớ VRAM". Thực tế tàn nhẫn hơn nhiều:
- Trên điện thoại: sập trắng màn hình, hoặc hệ điều hành lập tức tắt tab trình duyệt
- Trên kính thực tế ảo VR: tụt khung hình trầm trọng. Rớt khung hình trong kính VR không chỉ đơn thuần là "hơi giật", mà nó trực tiếp gây ra cảm giác buồn nôn, chóng mặt
- Trên máy tính để bàn: kết cấu bắt đầu nhấp nháy, mất chi tiết, tốc độ khung hình tụt dốc không phanh
Một nhà phát triển từng chia sẻ trên Reddit khi xây dựng một phòng trưng bày WebXR: anh nạp 60 bức ảnh lập thể lên kính Meta Quest. Lúc đầu mọi thứ chạy bình thường, nhưng càng về sau ứng dụng càng chập chờn cho đến khi sập hoàn toàn. Anh đã mất nhiều ngày gỡ lỗi mã nguồn, chỉ để nhận ra bản thân chưa từng nghiêm túc tính toán đến mức chiếm dụng VRAM: anh liên tục nhồi nhét ảnh JPEG thô lên GPU.
Hai Con Đường Nén Mô Hình 3D
Nén mô hình 3D chủ yếu phân chia thành hai hướng đi chiến lược:
Nén đỉnh lưới: lưu trữ tọa độ đỉnh, vector pháp tuyến, UV và các thuộc tính hình học khác theo phương thức cô đọng hơn. Ví dụ thay thế số thực 32-bit bằng số nguyên 16-bit (gọi là lượng tử hóa). Các giải pháp hàng đầu gồm: Draco, MeshOpt, KHR_mesh_quantization.
Nén kết cấu: giữ cho các bức ảnh luôn ở trạng thái nén ngay cả khi đã nạp vào bên trong VRAM. Phần cứng GPU sẽ giải mã tức thì từng khối điểm ảnh nhỏ ngay khi lấy mẫu mà hầu như không tốn hiệu năng. Giải pháp hàng đầu hiện nay: KTX2 kết hợp Basis Universal.
| Tiêu chí | Nén đỉnh lưới | Nén kết cấu |
|---|---|---|
| Mục tiêu cắt giảm | Dữ liệu hình học | Ảnh kết cấu |
| Hiệu quả điển hình | Giảm dung lượng tệp từ 50 đến 90% | Giảm dung lượng tệp 50-70%, giảm VRAM 75% |
| Có mất mát chất lượng? | Có, giảm độ chính xác tọa độ | Có, giảm nhẹ chất lượng hình ảnh |
| Kịch bản tối ưu nhất | Mô hình có mật độ đỉnh dày đặc | Hầu hết mọi mô hình PBR |
| Đọc thêm chi tiết | Bài viết phần 2 | Bài viết phần 3 và 4 |
Một sai lầm rất phổ biến: chỉ dùng Draco nén đỉnh lưới rồi yên tâm rằng mô hình đã được tối ưu hoàn toàn. Nhưng các bức ảnh kết cấu mới chiếm tới 80% dung lượng. Cắt giảm một nửa số đỉnh có thể chỉ giúp thu nhỏ toàn bộ tệp được 10%. Bạn bắt buộc phải xử lý đồng thời cả hai yếu tố này.
Không Có Phương Pháp Nào Phù Hợp Cho Mọi Trường Hợp
Đây là thông điệp cốt lõi xuyên suốt toàn bộ chuỗi bài viết:
Mỗi nền tảng, mỗi thiết bị phần cứng và mỗi tình huống sử dụng khác nhau đều đòi hỏi một chiến lược nén hoàn toàn khác biệt.
| Kịch bản thực tế | Nút thắt cổ chai chính | Trọng tâm cần tối ưu |
|---|---|---|
| Trưng bày trên Web máy tính | Tốc độ tải tệp mạng | Dung lượng tệp lưu trữ |
| Trình duyệt di động | Bộ nhớ đồ họa VRAM | Nén kết cấu KTX2 |
| Kính thực tế ảo VR | VRAM và tốc độ khung hình | Nén kết cấu + Đơn giản hóa đỉnh lưới |
| Ứng dụng Mini App | Kích thước gói tải và độ tương thích | Giải pháp siêu nhẹ (MeshOpt) |
| Đại cảnh không gian lớn | VRAM và số lượng lệnh vẽ | Nén toàn diện + Kỹ thuật đa cấp chi tiết LOD |
Mỗi bài viết tiếp theo sẽ không chỉ đơn giản khuyên bạn "hãy dùng công cụ này là xong". Thay vào đó, chúng tôi sẽ phân tích cặn kẽ: công cụ đó phát huy sức mạnh nhất trong hoàn cảnh nào, khi nào nó có thể gây phản tác dụng và bạn nên dùng giải pháp nào thay thế.
Các Bước Tiếp Theo
Bài viết này đã phác thảo trọn vẹn bức tranh tổng thể của vấn đề. Trong bài tiếp theo, chúng ta sẽ bắt tay vào thực hành với bộ ba công cụ nén đỉnh lưới: Lượng tử hóa, MeshOpt và Draco.