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.

Kris
Nén mô hình 3DglTFWebGLHiệu suất

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ạoChi tiết bên trongTỷ lệ điển hìnhGhi chú quan trọng
Bản đồ kết cấualbedo, normal, roughness, metallic, AO...70 đến 85%Luôn là thành phần nặng nhất
Dữ liệu đỉnh lướivị trí position, pháp tuyến normal, UV, tiếp tuyến tangent, màu đỉnh10 đến 20%Phụ thuộc vào độ phức tạp hình học
Hoạt cảnh chuyển độngxương khớp, trọng số da skinning, khung hình khóa0 đế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, cameraDướ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.

Phân tích các bản đồ kết cấu PBR của một mô hình 3D

"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ườngGiá 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.

So sánh dung lượng lưu trữ trên ổ đĩa và độ nở bộ nhớ VRAM của GPU

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ướiNén kết cấu
Mục tiêu cắt giảmDữ liệu hình họcẢnh kết cấu
Hiệu quả điển hìnhGiả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ấtMô hình có mật độ đỉnh dày đặcHầu hết mọi mô hình PBR
Đọc thêm chi tiếtBài viết phần 2Bà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ínhTrọng tâm cần tối ưu
Trưng bày trên Web máy tínhTốc độ tải tệp mạngDung lượng tệp lưu trữ
Trình duyệt di độngBộ nhớ đồ họa VRAMNén kết cấu KTX2
Kính thực tế ảo VRVRAM và tốc độ khung hìnhNén kết cấu + Đơn giản hóa đỉnh lưới
Ứng dụng Mini AppKích thước gói tải và độ tương thíchGiải pháp siêu nhẹ (MeshOpt)
Đại cảnh không gian lớnVRAM 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.

Công cụ liên quan

6
Xem tất cả
Nén mô hình 3D
Chuyển mô hình 3D thành ảnh
Trình xem mô hình 3D
Nén đỉnh mô hình 3D
Chụp ảnh STL
Trình xem GLB