GPU 纹理压缩
2026/7/26大约 7 分钟
GPU 纹理压缩详解 (BC / ASTC / ETC)
引言:为什么需要 GPU 纹理压缩
一张未压缩的 1024×1024 RGBA32 贴图占 4 MB 显存。一个场景成百上千张贴图,显存和带宽瞬间爆炸。GPU 纹理压缩要解决两件事:
- 省显存 / 省带宽:贴图在显存里始终保持压缩态,采样时由纹理单元现场解码。
- 且必须满足一个硬约束:能被 GPU 在采样时实时、随机地硬件解码。
正是这个"随机 + 实时"的约束,决定了 GPU 纹理压缩不能用 PNG/JPEG,而要走块压缩(Block Compression) 路线。
一、共同基础:块压缩
无论 BC 还是 ASTC,底层思想一致:
四个关键性质:
| 性质 | 含义与价值 |
|---|---|
| 定块 | 切成固定小块(BC 恒 4×4 纹素;ASTC 可变) |
| 定长 | 每块压成固定字节数 → 压缩率可预测、内存可预算 |
| 随机访问 | 采样任意纹素只需解码它所在的一个块,常数时间 —— 硬件采样的硬需求 |
| 有损 | 固定比特预算 → 丢弃信息 |
为什么不能用 PNG / JPEG
PNG/JPEG 是整图、变长、非随机访问的:要取一个像素,几乎得解开整张图。GPU 采样一个纹素时无法只解一小块,所以它们不能直接作为 GPU 纹理(只能先全解压成 RGBA 再上传,那就没有省显存的意义了)。
二、收益:码率与内存对比
块压缩把每纹素的比特数(bpp)从未压缩的 32 bpp 大幅降低:

- 未压缩 RGBA32 = 32 bpp;BC1 = 4 bpp(8:1);BC7/BC3 = 8 bpp(4:1)。
- ASTC 靠块大小在 8 ~ 0.89 bpp 之间连续可选。
- 显存与带宽收益与 bpp 成正比 —— 这是纹理压缩在性能优化里的核心价值。
三、BC 系列(Block Compression,即老 DXT / S3TC 家族)
基本手法:端点 + 插值 + 索引
以 BC1(DXT1) 为例,对每个 4×4 块:把这 16 个纹素的颜色近似看作分布在颜色空间的一条线段上,只存两端点,中间靠插值:

每个块存:
· 2 个端点颜色 (RGB565, 各 16 bit) = 32 bit
· 由端点插值出 4 色调色板 (端点0/1、1/3、2/3处)
· 16 个纹素各存 1 个 2-bit 索引 (指向 4 色之一) = 32 bit
合计 64 bit = 8 字节 / 16 纹素 → 4 bpp本质:假设小块内颜色变化不大、可用"两端点之间的一条线"近似,每个纹素只存"落在线上哪个刻度"的索引。
BC 各变体分工
| 格式 | 内容 | bpp | 典型用途 |
|---|---|---|---|
| BC1 (DXT1) | RGB(+1bit alpha) | 4 | 不透明漫反射贴图 |
| BC3 (DXT5) | RGB + 插值 alpha | 8 | 带平滑透明的贴图 |
| BC4 | 单通道插值 | 4 | 高度图 / 灰度 / 遮罩 |
| BC5 | 双通道 (BC4×2) | 8 | 法线贴图(存 XY,重建 Z) |
| BC6H | HDR RGB (16bit float) | 8 | HDR 环境 / 光照贴图 |
| BC7 | 高质量 RGBA (LDR) | 8 | 高质量彩色 / 带 alpha |
BC1~5 vs BC6H / BC7 的进化
- BC1~5:简单"两端点一条线 + 索引",一个块只有一对端点。
- BC6H / BC7:引入分区(partition) 与多模式(mode)—— 一个块可切成几个区域、各用自己的端点对,并能选不同比特分配方案。于是能拟合更复杂的块,同 8 bpp 下质量大幅提升。BC7 是 LDR 彩色贴图的高质量首选。
四、ASTC(Adaptive Scalable Texture Compression)
由 ARM / AMD 主导,移动端主流。它把块压缩的灵活性推到极致,两个关键词:
Scalable —— 块大小可变、码率可选
ASTC 每块恒为 128 bit(16 字节),但这个块可覆盖 4×4 到 12×12(含非正方形)不等的纹素:
| 块大小 | 码率 | 定位 |
|---|---|---|
| 4×4 | 8 bpp | 质量最高 |
| 6×6 | ≈ 3.56 bpp | 平衡 |
| 8×8 | 2 bpp | 省 |
| 12×12 | ≈ 0.89 bpp | 最省 |
同一格式,仅靠选块大小就能在"质量 ↔ 体积"间平滑取舍 —— 这是 BC(固定 4×4)做不到的。
Adaptive —— 块内布局自适应
每个 128-bit 块里有个 Block Mode(配置字段),描述这 128 位如何分配,可自适应调整:
| 可调项 | 作用 |
|---|---|
| 分区(最多 4 个) | 块内分区域、各自独立端点 → 拟合复杂块 |
| 端点格式 / 精度 | 按需选颜色端点编码方式与位数 |
| 权重网格 | 逐纹素插值权重存在可低于块分辨率的网格上再上采样,权重分辨率与块大小解耦 |
正因每块能自适应选择这些配置,ASTC 在同码率下质量普遍优于 BC,并原生支持 1~4 通道、LDR 与 HDR、2D 与 3D。代价是解码更复杂、编码(压缩)很慢。
五、ETC(Ericsson Texture Compression)
移动端的老标准,了解即可:
- ETC1:RGB,4 bpp,无 alpha;OpenGL ES 2.0 时代标配。
- ETC2:RGB / RGBA,向后兼容 ETC1;OpenGL ES 3.0 标配。
- 现在移动端首选 ASTC,ETC2 作为老设备回退。
六、横向对比
| 维度 | BC 系列 | ASTC | ETC2 |
|---|---|---|---|
| 块大小 | 固定 4×4 | 可变 4×4~12×12 | 固定 4×4 |
| 每块字节 | 8 或 16 | 恒 16(128 bit) | 8 或 16 |
| 码率 | 4 / 8 bpp | 0.89~8 bpp 连续 | 4 / 8 bpp |
| HDR | BC6H | 支持 | 不支持 |
| 通道 | 按格式固定 | 1~4 灵活 | RGB/RGBA |
| 平台 | 桌面 / 主机(DX) | 移动端主流(现代 GPU 普遍支持) | 移动端(老) |
| 质量 / 码率 | BC7 已很好 | 通常更优、更灵活 | 一般 |
| 编码速度 | 较快 | 较慢 | 较快 |
七、选型实践
| 场景 | 推荐 |
|---|---|
| 桌面/主机 彩色贴图 | BC7(高质)/ BC1(省) |
| 桌面/主机 法线贴图 | BC5(避免 BC1 破坏法线) |
| 桌面/主机 HDR 贴图 | BC6H |
| 桌面/主机 高度/遮罩 | BC4 |
| 移动端 通用 | ASTC(按重要度选块大小:重要 4×4/6×6,次要 8×8+) |
| 移动端 老设备回退 | ETC2 |
八、注意点
- 法线贴图别用 BC1:三通道线性压缩会破坏法线方向;用 BC5(XY 双通道重建 Z)或 ASTC。
- sRGB vs Linear:颜色贴图按 sRGB 采样、法线/数据贴图按 Linear,压缩格式要选对对应变体。
- Mipmap:压缩与 Mipmap 配合能进一步省远处采样带宽(呼应各向异性/Mipmap 抗锯齿)。
- 不要二次压缩:已压缩贴图再压会累积损失;从无损源重新压。
- 编码耗时:ASTC / BC7 高质量编码很慢,通常离线在资源导入/打包时完成。
附:核心概念速查
| 概念 | 说明 |
|---|---|
| 块压缩 | 切固定块、每块定长、随机访问、硬件实时解码 |
| bpp | 每纹素比特数,越低越省(未压缩 RGBA32 = 32) |
| 端点 + 索引 | BC 的核心:存两端点色 + 每纹素索引落点 |
| 分区 / 模式 | BC6H/BC7、ASTC 拟合复杂块的手段 |
| ASTC 可变块 | 4×4~12×12,码率 8~0.89 bpp 连续可选 |
| BC5 | 双通道,法线贴图首选 |
| BC6H | HDR 纹理压缩 |
总结
- GPU 纹理压缩使用块压缩(Block Compression)实现随机访问和硬件实时解码,与 PNG/JPEG 等整图变长压缩有本质区别。
- BC 系列以固定 4×4 块为基础,通过端点和索引插值实现压缩,BC1~5 适合不同类型素材,BC6H/BC7 引入分区和多模式带来更高质量。
- ASTC 支持可变块大小(4×4 到 12×12),码率在 0.89~8 bpp 间连续可选,块内布局自适应,质量和灵活性更高,是移动端主流方案。
- ETC2 作为移动端老标准,现主要用于老设备回退。
- 选型上桌面/主机推荐 BC 系列(BC7 彩色、BC5 法线、BC6H HDR),移动端首选 ASTC 并按素材重要度选择块大小。
