Pelajaran Pertama Merampingkan Model 3D: Tiga Teknik Kompresi Vertex
Berapa byte yang sebenarnya dikonsumsi data vertex? Kuantisasi, MeshOpt, dan Draco: panduan memilih alat yang tepat untuk tiap kebutuhan, karena tidak ada solusi terbaik selain solusi yang paling cocok.
Pada artikel sebelumnya, saat membedah struktur file GLB, kita melihat bahwa tekstur memakan 80% ukuran file sementara vertex hanya 10% hingga 20%. Apakah ini berarti kompresi vertex tidak penting?
Sama sekali tidak. Ketika tekstur model sudah dikompresi ke format KTX2 pada model padat geometri, sisa 20% porsi vertex tersebut dapat dipangkas hingga setengah atau bahkan 90%. Yang terpenting, kompresi vertex adalah optimasi berbiaya rendah dengan dampak instan: beberapa baris perintah dan decoder ringan langsung membuat file jauh lebih ramping.
Artikel ini membahas tiga hal utama: ukuran nyata data vertex, karakteristik Kuantisasi, MeshOpt, dan Draco, serta kesimpulan praktis: Tidak ada solusi mutlak terbaik, yang ada hanyalah solusi yang paling sesuai.
Berapa Ukuran Asli Satu Vertex?
Dalam standar glTF, setiap vertex tersusun dari beberapa atribut geometri:
| Atribut Geometri | Fungsi | Presisi Default | Ukuran per Vertex (Byte) |
|---|---|---|---|
| position (posisi) | Koordinat spasial 3D | 3 × float32 | 12 byte |
| normal (arah normal) | Menentukan interaksi pencahayaan | 3 × float32 | 12 byte |
| tangent (tangen) | Perhitungan peta normal | 4 × float32 | 16 byte |
| texcoord_0 (UV) | Koordinat pemetaan tekstur | 2 × float32 | 8 byte |
| color (warna vertex) | Pewarnaan langsung level vertex | 4 × float32 | 16 byte |
Satu vertex dengan atribut PBR lengkap dapat menghabiskan 48 hingga 64 byte. Model dengan 100.000 vertex membutuhkan 5 hingga 6MB hanya untuk data geometrinya.
Perhatikan bahwa hampir semua atribut menggunakan float32 (bilangan desimal 32-bit). Dari sinilah ruang optimasi terbuka lebar, karena mata manusia tidak memerlukan presisi desimal setinggi itu pada sebagian besar atribut visual.
Teknik 1: Kuantisasi (Quantization)
Kuantisasi adalah prinsip matematika dasar di balik semua teknik kompresi geometri; Draco dan MeshOpt juga memanfaatkannya di tingkat internal.
Kuantisasi (memetakan bilangan desimal presisi tinggi ke bilangan bulat berpresisi lebih rendah) ibarat menyederhanakan 3.14159265 menjadi 3.14. Alih-alih menyimpan setiap desimal dengan 32-bit, koordinat dipetakan ke dalam bilangan bulat berjangkauan lebih kecil.
Nilai Asli: position.x = 1.234567 (float32, 4 byte)
Terkonsolidasi: position.x = 1234 (int16, 2 byte) + skala & offset pemulihan
Perbandingan ukuran sebelum dan sesudah kuantisasi:
| Atribut | Ukuran float32 | Terkuantisasi (16-bit) | Rasio Penghematan |
|---|---|---|---|
| position | 12 byte | 6 byte | 50% |
| normal | 12 byte | 6 byte (atau 4 byte dengan int8) | 50% hingga 67% |
| tangent | 16 byte | 4 hingga 8 byte | 50% hingga 75% |
| texcoord | 8 byte | 4 byte | 50% |
Kuantisasi memangkas ukuran vertex dari 48-64 byte menjadi 16-24 byte, mengurangi beban geometri hingga separuh ukuran aslinya.
Kapan Menggunakan Kuantisasi Murni?
- Anda ingin merampingkan ukuran file tanpa memerlukan rasio kompresi ekstrem.
- Anda menginginkan ketergantungan decoder nol; ekstensi standar
KHR_mesh_quantizationdidukung secara native oleh Three.js dan Babylon.js tanpa library tambahan. - Platform target sangat sensitif terhadap ukuran bundel (seperti mini program atau aplikasi web ringan).
Kapan Menghindarinya?
- Model berukuran sangat kecil dengan detail presisi tinggi (seperti komponen perhiasan atau suku cadang industri milimeter), di mana deviasi 0.1mm dapat terlihat pada jarak dekat.
Teknik 2: MeshOpt
MeshOpt adalah ekstensi resmi EXT_meshopt_compression pada glTF yang memadukan rasio kompresi tinggi dengan kecepatan dekompresi super cepat.
Cara kerjanya adalah dengan menguantisasi atribut terlebih dahulu, lalu menerapkan enkoding entropi tanpa penurunan kualitas (Lossless Entropy Coding) pada data integer tersebut.
- Rasio kompresi: 30% hingga 50% lebih kecil daripada kuantisasi murni.
- Kecepatan dekompresi: luar biasa cepat, mampu memproses puluhan juta vertex per detik pada satu thread CPU.
- Ukuran library decoder: sangat kecil (~20-30KB).
- Kompatibilitas: didukung secara native di Three.js dan Babylon.js.
Teknik 3: Draco
Draco adalah solusi kompresi dari Google yang berfokus pada efisiensi ukuran file maksimal.
Perbedaan mendasarnya: Draco mereorganisasi topologi segitiga mesh secara menyeluruh, menyusun kembali konektivitas antar-vertex agar dapat dikemas dalam ukuran paling minimal.
- Rasio kompresi: tertinggi di antara ketiganya, mampu mencapai pengurangan lebih dari 90% pada model berdensitas tinggi.
- Kecepatan dekompresi: relatif paling lambat di antara ketiganya.
- Ukuran decoder: lebih besar (~100-200KB sebagai modul WebAssembly terpisah).
Kapan Menggunakan Draco?
- Model berukuran raksasa dengan jutaan vertex padat (seperti hasil pemindaian 3D atau topografi medan).
- Adegan yang dimuat sekali dan digunakan dalam durasi lama.
Tabel Pemilihan Solusi Kompresi Geometri
| Solusi | Rasio Kompresi (vs float32) | Kecepatan Dekompresi | Ukuran Decoder | Penurunan Kualitas? | Ekstensi glTF |
|---|---|---|---|---|---|
| Kuantisasi Murni | ~50% | Native tanpa decoder | 0 byte | Ya (presisi angka) | KHR_mesh_quantization |
| MeshOpt | ~25%-35% | Sangat Cepat | ~25KB | Ya (presisi angka) | EXT_meshopt_compression |
| Draco | ~10%-20% | Sedang | ~100-200KB | Ya (presisi & topologi) | KHR_draco_mesh_compression |
Kompatibilitas Platform:
| Platform | Kuantisasi Murni | MeshOpt | Draco |
|---|---|---|---|
| Web Desktop | Didukung native | Didukung native | Membutuhkan decoder |
| Web Mobile | Didukung native | Didukung native | Decoder cukup berat |
| WebXR / VR | Didukung native | Sangat direkomendasikan | Perlu kehati-hatian |
| Mini Program | Sangat direkomendasikan | Sangat direkomendasikan | Sebaiknya dihindari |
Praktik Nyata dengan gltfpack
Alat CLI gltfpack memungkinkan Anda mengaplikasikan kuantisasi dan MeshOpt dalam satu perintah:
# Menguantisasi model ke 16-bit dan menambahkan kompresi MeshOpt
gltfpack -i model.glb -o model-packed.glb -cc
Pilihan perintah umum:
# Kuantisasi saja tanpa MeshOpt (tanpa dependensi decoder)
gltfpack -i model.glb -o model-quant.glb
# Kuantisasi + kompresi MeshOpt penuh
gltfpack -i model.glb -o model-meshopt.glb -cc
# Menyederhanakan geometri menjadi 50% segitiga sekaligus kompresi
gltfpack -i model.glb -o model-simplify.glb -cc -si 0.5
Hasil pengujian pada model PBR 5MB dengan 120 ribu vertex:
| Jenis Pemrosesan | Ukuran File | Keterangan |
|---|---|---|
| Asli (float32) | 5.0MB | Standar awal |
| Kuantisasi saja (default) | 2.6MB | Menyusut separuh tanpa perbedaan visual |
MeshOpt penuh (-cc) | 1.7MB | Hemat tambahan 35% dengan pemuatan cepat |
Kesalahan Umum & Solusinya
- Arah normal terbalik setelah kuantisasi: Gunakan minimal presisi 16-bit untuk normal atau format 8-bit octahedral.
- Material hilang setelah dekompresi Draco: Draco hanya mengompresi geometri; pastikan loader tekstur terkonfigurasi dengan benar secara paralel.
- Model bergeser dari posisinya: Pindahkan posisi model mendekati titik pusat (0,0,0) sebelum proses kuantisasi.
Langkah Selanjutnya
Geometri vertex sudah berhasil dirampingkan. Namun tekstur masih menyumbang porsi terbesar file 3D. Artikel berikutnya akan mengupas tuntas mengapa format PNG/JPG memboroskan memori VRAM GPU dan bagaimana format native GPU menyelesaikannya.