游戏开发中的图像格式选择 - 纹理压缩与渲染性能
为什么游戏开发需要不同的图像格式
游戏中的图像(纹理)与 Web 图像有根本不同的需求。GPU 需要能直接在显存中随机访问的压缩格式,而非需要完整解压的 JPEG/PNG。
游戏纹理的特殊需求:
- GPU 直接采样:纹理必须以 GPU 可直接读取的格式存储在显存中。JPEG/PNG 需要完整解压为未压缩像素才能使用
- 随机访问:渲染时 GPU 需要随机访问纹理的任意区域(纹理过滤),不能像流式解码那样顺序读取
- 固定压缩比:GPU 纹理压缩使用固定大小的块(如 4x4 像素),确保任意位置的访问时间恒定
- 显存限制:游戏可能同时加载数千张纹理,压缩率直接决定能加载多少内容
结果:游戏使用专门的 GPU 纹理压缩格式(BC1-7、ASTC、ETC2),而非 Web 常用的 JPEG/PNG/WebP。
GPU 纹理压缩机制 - BCn 系列(DirectX)
BCn(Block Compression)是 DirectX 平台的标准纹理压缩格式族,将纹理分为 4x4 像素块独立压缩。
BCn 格式一览:
- BC1(DXT1):RGB,4 位/像素(8:1 压缩比)。每个 4x4 块存储 2 个端点颜色 + 16 个 2 位索引。适合不需要 Alpha 的漫反射纹理
- BC3(DXT5):RGBA,8 位/像素(4:1)。BC1 的 RGB + 独立的 Alpha 块。适合需要透明度的纹理
- BC4:单通道,4 位/像素。适合高度图、粗糙度图等单通道数据
- BC5:双通道,8 位/像素。适合法线贴图(仅存储 XY,Z 通过计算恢复)
- BC7:RGBA,8 位/像素。质量最高的通用格式,支持多种分区模式。适合高质量纹理
选择指南:漫反射纹理用 BC1/BC7,法线贴图用 BC5,带 Alpha 用 BC3/BC7,单通道数据用 BC4。BC7 质量最好但仅 DX11+ 硬件支持。
ASTC - 移动端和跨平台标准
ASTC(Adaptive Scalable Texture Compression)是 ARM 开发的纹理压缩格式,支持可变块大小,在移动平台广泛使用。
ASTC 特点:
- 可变块大小:从 4x4 到 12x12,提供从 8 位/像素到 0.89 位/像素的连续压缩率范围
- 统一格式:一种格式覆盖 LDR/HDR、1-4 通道、2D/3D 纹理
- 高质量:在相同压缩率下质量通常优于 BCn 和 ETC2
块大小选择:
- 4x4(8 bpp):最高质量,适合法线贴图和 UI 纹理
- 6x6(3.56 bpp):质量和大小的良好平衡,适合大多数漫反射纹理
- 8x8(2 bpp):较高压缩,适合远景纹理和不太重要的资源
平台支持:iOS(A8+)、Android(大多数现代设备)、macOS(Apple Silicon)。桌面端通过 Vulkan/OpenGL 扩展支持。
容器格式 - DDS、KTX2 和 Basis Universal
GPU 纹理压缩数据需要容器格式来存储元数据(尺寸、格式、Mipmap 层级等)。
主要容器格式:
- DDS(DirectDraw Surface):DirectX 生态标准。支持所有 BCn 格式、Mipmap、立方体贴图、纹理数组。Windows/Xbox 游戏的首选
- KTX2(Khronos Texture 2.0):Vulkan/OpenGL 生态标准。支持所有 GPU 格式、Basis Universal 超压缩、Zstandard 额外压缩。跨平台首选
- Basis Universal:中间格式,可在运行时快速转码为目标平台的原生格式(BC1-7、ASTC、ETC2)。一份文件适配所有平台
Basis Universal 的优势:
- 打包时只需存储一份纹理数据,运行时根据 GPU 能力转码
- 转码速度极快(< 1ms/纹理),不影响加载性能
- 显著减少游戏安装包大小(无需为每个平台存储不同格式)
平台特定的最佳格式选择
不同游戏平台的 GPU 支持不同的纹理格式,需要针对性选择。
平台格式推荐:
- PC(Windows/DirectX):BC7(高质量)、BC1/BC3(兼容性)。DX11+ 硬件全面支持 BC7
- PC(Vulkan):BC7 或 ASTC(如果目标硬件支持)
- iOS:ASTC(A8 芯片及以上全面支持)。旧设备用 PVRTC(已过时)
- Android:ASTC(大多数现代设备)、ETC2(广泛兼容的降级方案)
- 主机(PS5/Xbox Series):BC7(最高质量)、BC1-5(节省显存时)
- Web(WebGL/WebGPU):Basis Universal → 运行时转码为设备支持的格式
多平台策略:使用 Basis Universal 作为源格式,构建时或运行时转码为目标平台格式。或在构建流水线中为每个平台生成对应格式的资源包。
纹理图集与流式加载架构设计
大型游戏需要管理数千张纹理,图集打包和流式加载是性能优化的关键。
纹理图集(Texture Atlas):
- 将多张小纹理打包到一张大纹理中,减少 Draw Call 和状态切换
- 图集大小通常为 2048x2048 或 4096x4096(GPU 最大纹理尺寸限制)
- 需要处理边缘出血(bleeding):在子纹理边缘添加 1-2 像素的填充防止采样时混入相邻纹理
虚拟纹理(Virtual Texturing):
- 将超大纹理(如地形)分割为小块(tiles),仅加载当前可见区域的块
- 类似虚拟内存的概念:逻辑上是一张巨大纹理,物理上只有部分驻留在显存
- Unreal Engine 的 Virtual Texture 和 id Tech 的 MegaTexture 是典型实现
Mipmap 流式加载:
- 先加载低分辨率 Mipmap 快速显示,再异步加载高分辨率层级
- 根据相机距离动态调整驻留的 Mipmap 层级,节省显存
- Unity 的 Texture Streaming 和 UE 的 Texture Streaming 系统