Tại sao một Texture Atlas lớn có thể tối ưu hơn nhiều Texture nhỏ?
Minh Khoa
Tác giả
Khi nhìn 20 icon nhỏ trong một màn hình UI, phản xạ rất tự nhiên là:
Ảnh nhỏ thì chắc render nhẹ hơn một ảnh lớn.
Đúng nếu chỉ nhìn từng file. Nhưng GPU không chỉ quan tâm ảnh lớn hay nhỏ. Nó còn quan tâm mỗi lần phải đổi Texture, Material và trạng thái render.
Texture Atlas nhanh hơn chủ yếu vì giảm số lần đổi Texture và mở đường cho Batching — không phải vì một ảnh lớn tự nhiên dùng ít VRAM hơn.
## 1. Hãy tưởng tượng GPU là một người thợ in
Bạn có 20 hình và mỗi hình nằm trên một tờ giấy riêng.
Cứ in xong một hình, người thợ lại phải:
- Bỏ tờ giấy cũ.
- Lấy tờ giấy mới.
- Căn lại máy.
- In tiếp.
Nếu 20 hình nằm trên cùng một tờ lớn, người thợ chỉ cần nạp tờ giấy một lần, sau đó in từng vùng khác nhau trên tờ đó.
Trong GPU, vùng cần lấy được xác định bằng UV:
Nhiều Texture:
Bind A → Draw → Bind B → Draw → Bind C → Draw
Texture Atlas:
Bind Atlas → Draw A, B, C bằng các vùng UV khác nhau
Texture Atlas không làm hình A, B, C biến mất. Nó chỉ giúp chúng dùng chung một nguồn Texture.
2. Lợi ích lớn nhất: giảm Draw Call và Batch Break
Hai Sprite có thể dùng cùng Shader, nhưng nếu chúng dùng hai Texture riêng thì Unity thường phải đổi trạng thái render giữa chúng. Việc đổi Texture hoặc Material có thể làm ngắt Batch.
Khi đưa các Sprite vào cùng một Atlas:
- Chúng có thể dùng chung Texture và Material.
- Unity dễ gom các Sprite tương thích vào cùng Batch hơn.
- CPU phải chuẩn bị và gửi ít lệnh render hơn.
- GPU ít phải chờ những lần đổi trạng thái không cần thiết.
Ví dụ một màn hình có 20 icon:
20 Texture riêng
→ có thể tạo ra nhiều Batch / Draw Call
1 Sprite Atlas
→ có thể giảm còn 1 hoặc vài Batch
Không nên hiểu cứng rằng “1 Atlas luôn bằng 1 Draw Call”. Mask, Material, Shader Pass, thứ tự render, Canvas và Sorting vẫn có thể làm Batch bị tách.
3. Atlas có tự động tiết kiệm VRAM không?
Không chắc.
Giả sử có 16 Texture, mỗi Texture là 256 × 256:
16 × 256 × 256 = 1,048,576 texel
Nếu xếp vừa vào một Atlas :