Any3DAny3D
·Any3D Team

不同平台不同命:壓縮方案選型指南

3d-compressiontexture-compressionvertex-compressionoptimizationpipeline

前 4 篇分別講了頂點壓縮和貼圖壓縮的工具。但工具會用是一回事,該用哪個、在什麼場景下用是另一回事。這篇就是來回答這個問題的——而且盡量讓你看完就能直接拍板。

讀完這一篇你應該能回答:我的專案跑在什麼平台,首屏瓶頸是下載還是顯存,貼圖和頂點各該上哪套方案。

先定調:場景驅動,不是工具驅動

整篇文章只有一條核心原則,也是這個系列反覆強調的:

沒有「最好的」壓縮方案,只有「最匹配場景」的方案。

影響選擇的三個變數:

  1. 平台/裝置:桌面 PC、行動瀏覽器、VR 頭盔、小程式——能力天差地別
  2. 使用方式:是一次性展示(電商產品頁),還是長時間沉浸(VR 遊戲)
  3. 首要瓶頸:是下載速度慢,還是顯存不夠,還是解碼卡首屏

先把瓶頸想清楚,再回來選工具。下面這張矩陣就是把這套思路固化下來。

核心決策矩陣:平台 × 推薦方案

這是全文最重要的一張表。按平台分,給出貼圖和頂點各自的推薦方案,以及理由。

平台 / 場景貼圖方案頂點方案主要瓶頸關鍵理由
桌面 Web(PC 瀏覽器)KTX2 或 WebPMeshOpt / 量化下載速度顯存寬裕,重點是檔案小、載入快
行動 Web(手機瀏覽器)KTX2(必上)MeshOpt顯存手機顯存緊,貼圖必須塊壓縮
WebXR / VR 頭盔KTX2(必上)MeshOpt + LOD顯存 + 幀率顯存爆炸會崩,掉幀會眩暈
微信小程式KTX2 / WebPMeshOpt / 純量化包體 + 相容性包大小受限,避免重型解碼器
電商產品展示WebP(輕)/ KTX2(精)MeshOpt首屏速度要求秒開,體積換速度
大型場景 / 數位孿生KTX2(必上)MeshOpt + Draco + LOD顯存 + draw call貼圖多、模型大,全方位壓

幾個值得記住的判斷:

  • 只要顯存是瓶頸,KTX2 就必上(行動、VR、大場景都是)
  • 下載速度是瓶頸、顯存寬裕時,WebP 也夠用(桌面、電商)
  • 小程式這類對包體敏感的環境,優先 MeshOpt 而不是 Draco——解碼器小、相容好
  • 超大模型才考慮 Draco,絕大多數中小模型 MeshOpt 更均衡

貼圖格式全維度對比

光知道「上 KTX2」還不夠。具體到貼圖格式,把所有維度攤開看:

格式檔案大小顯存佔用上傳速度相容性畫質適用場景
PNG大(解壓縮後)極廣無損需要精確數值/透明,或舊平台兜底
JPG極小大(解壓縮後)極廣有損顏色貼圖、網路傳輸優先
WebP很小大(解壓縮後)較廣桌面 Web、追求下載速度
AVIF更小大(解壓縮後)漸進新平台、極致壓縮
KTX2 (ETC1S)極小需轉碼中(顏色夠用)顏色貼圖、行動/VR
KTX2 (UASTC)需轉碼法線/資料貼圖

注意前三行(PNG/JPG/WebP/AVIF)的顯存佔用都是「大」——無論磁碟多小,進了顯存都得解壓縮回原始像素。這是傳統格式的根本限制。

混合策略很常見:關鍵的顏色貼圖用 KTX2 保證顯存,次要貼圖(比如一個小 emissive)用 WebP 省事。不必一刀切全 KTX2,按瓶頸分配。

決策流程圖:一步步選

矩陣是結果,流程圖告訴你怎麼走到那個結果。

你的專案跑在哪?
│
├─ 桌面 Web(顯存寬裕)
│   └─ 首屏慢嗎?
│       ├─ 慢 → WebP(或 AVIF)+ MeshOpt  [追求下載速度]
│       └─ 不慢,但模型多 → KTX2 + MeshOpt [為未來留餘地]
│
├─ 行動 Web / VR / 大場景(顯存緊)
│   └─ 貼圖必上 KTX2(顏色 ETC1S,資料 UASTC)
│       └─ 模型頂點超密?
│           ├─ 是 → + Draco [極限壓縮,能接受慢解碼]
│           └─ 否 → + MeshOpt [均衡]
│
└─ 小程式 / 受限執行時
    └─ 包體敏感嗎?
        ├─ 敏感 → 純量化或 MeshOpt + WebP [零/小解碼器]
        └─ 還行 → MeshOpt + KTX2 [常規組合]

頂點壓縮 vs 貼圖壓縮:該投哪個

經常有人問:預算有限,先最佳化哪頭?看模型構成:

模型特徵投入重點原因
PBR 角色/產品(貼圖多)貼圖壓縮貼圖佔 80%+,投頂點回報低
CAD/掃描模型(頂點超密、貼圖少)頂點壓縮頂點是主要體積
動畫角色(骨骼+蒙皮)兩頭都投,但頂點優先 Draco 之外動畫資料也佔體積,Draco 對動畫支援弱
建築/場景(大、中等貼圖)貼圖 + LOD貼圖省顯存,LOD 省 draw call

一個粗略的收益排序:貼圖 KTX2 > 頂點 MeshOpt/量化 > 幾何簡化(LOD) > 頂點 Draco。先做收益高的。

混合策略:關鍵貼圖 KTX2,次要貼圖 WebP

不是所有貼圖都值得壓成 KTX2。一個典型的 PBR 材質有 5-6 張貼圖,全壓 KTX2 工程量大,有時也不必要。

實用分法:

  • 必 KTX2:albedo(大、顏色)、normal(精度敏感)、roughness/metallic(影響光照)
  • 可 WebP/JPG:emissive(通常小)、AO(中低頻)、細節法線(如果有的話)

判斷標準:貼圖大不大、是不是高頻細節、會不會頻繁取樣。三者都中 → KTX2;都不中 → 傳統格式省事。

自動化選型:gltf-transform 一鍵搞定

gltf-transformoptimize 命令是絕大多數場景的銀彈——它會自動判斷貼圖類型、按推薦策略壓縮貼圖、可選地處理頂點。

# 安裝
npm install -g @gltf-transform/cli

# 標準最佳化:貼圖 KTX2 + 頂點 MeshOpt + 去冗餘
gltf-transform optimize model.glb model-optimized.glb \
  --texture-compress basisu \
  --meshopt

參數說明:

參數作用預設
--texture-compress basisu貼圖壓成 KTX2(自動選 ETC1S/UASTC)
--meshopt頂點啟用 MeshOpt 壓縮
--simplify幾何簡化(減少頂點,有損)
--weld合併重複頂點
--prune移除未使用的節點/材質

一個適合行動端的「強力壓縮」組合:

gltf-transform optimize model.glb model-mobile.glb \
  --texture-compress basisu \
  --meshopt \
  --simplify --simplify-ratio 0.5 \
  --prune --weld

桌面端「溫和」組合(保留細節,只壓貼圖和頂點):

gltf-transform optimize model.glb model-desktop.glb \
  --texture-compress webp \
  --meshopt

編寫成可重用腳本

把上面封裝成按平台產出多個版本的腳本:

// compress.mjs —— 按 target 輸出不同壓縮版本
import { optimize } from "@gltf-transform/functions";
import { NodeIO } from "@gltf-transform/core";
import { KHRONOS_EXTENSIONS } from "@gltf-transform/extensions";

const io = new NodeIO().registerExtensions(KHRONOS_EXTENSIONS);

const targets = {
  // 行動端:KTX2 + MeshOpt + 簡化
  mobile: { texture: "basisu", meshopt: true, simplify: 0.5 },
  // VR:KTX2 + MeshOpt,不簡化(VR 近距離觀看)
  vr: { texture: "basisu", meshopt: true, simplify: null },
  // 桌面:WebP + MeshOpt,溫和
  desktop: { texture: "webp", meshopt: true, simplify: null },
};

const input = process.argv[2];
const doc = await io.read(input);

for (const [name, cfg] of Object.entries(targets)) {
  const out = doc.clone(); // 每個目標獨立副本
  await optimize(out, {
    textureCompression: cfg.texture,
    meshCompression: cfg.meshopt ? "meshopt" : null,
    simplify: cfg.simplify != null ? { ratio: cfg.simplify } : null,
  });
  await io.write(`model-${name}.glb`, out);
  console.log(`✓ model-${name}.glb`);
}
node compress.mjs model.glb
# 輸出 model-mobile.glb / model-vr.glb / model-desktop.glb

執行時按裝置載入對應版本(用 UA 或 WebGL 能力探測區分),首屏體驗最優。下一篇的端到端實戰會把這套完整串起來。

一句話備忘

  • 顯存是瓶頸 → KTX2,沒得選
  • 下載是瓶頸、顯存寬裕 → WebP/AVIF 也行
  • 解碼器體積敏感 → MeshOpt > 純量化 > Draco
  • 超大模型 → 才考慮 Draco
  • 拿不準 → gltf-transform optimize 一鍵跑,錯了再調

下一步

選型框架有了,最後一篇收官:從一個真實模型出發,走完 Blender 匯出、貼圖壓縮、頂點壓縮、引擎載入的全流程,並附上完整自動化腳本和系列速查表。

贊助支持