游戏开发中的图像格式选择 - 纹理压缩与渲染性能

· 9 分钟阅读

为什么游戏开发需要不同的图像格式

游戏中的图像(纹理)与 Web 图像有根本不同的需求。GPU 需要能直接在显存中随机访问的压缩格式,而非需要完整解压的 JPEG/PNG。

游戏纹理的特殊需求:

  • GPU 直接采样:纹理必须以 GPU 可直接读取的格式存储在显存中。JPEG/PNG 需要完整解压为未压缩像素才能使用
  • 随机访问:渲染时 GPU 需要随机访问纹理的任意区域(纹理过滤),不能像流式解码那样顺序读取
  • 固定压缩比:GPU 纹理压缩使用固定大小的块(如 4x4 像素),确保任意位置的访问时间恒定
  • 显存限制:游戏可能同时加载数千张纹理,压缩率直接决定能加载多少内容

结果:游戏使用专门的 GPU 纹理压缩格式(BC1-7、ASTC、ETC2),而非 Web 常用的 JPEG/PNG/WebP。

补充:Web 图像优先考虑文件体积与浏览器兼容性,而游戏优先考虑 GPU 绘制性能与 VRAM(显存)占用。JPEG 与 PNG 必须先由 CPU 解码再上传到 GPU,而 GPU 纹理压缩格式可由 GPU 直接读取,无需解码步骤。

  • 一般游戏项目中,纹理约占全部资源的 60-80%
  • AAA 级作品的纹理数据可达数十 GB,格式选择直接影响下载体积、载入时间与绘制性能
  • 选对格式可在维持视觉品质的同时把 VRAM 占用减少 50-75%

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+ 硬件支持。

补充说明:bpp 是 bits per pixel(每像素位数)的缩写。BC5 最适合法线贴图(Normal Map),它把 XY 两个分量独立高精度压缩,Z 分量由着色器重新计算。BC6H 用于 HDR(Half-Float) RGB 数据,适合环境贴图与 HDR 光照贴图等高动态范围纹理;BC7 提供高品质 RGB/RGBA,是现代游戏彩色纹理的标准。

  • 同为 8 位/像素时,BC7 相比 BC1 的 PSNR 提升约 2-4dB,渐变与边缘处的伪影明显减少
  • BC7 的编码耗时是 BC1 的 10-50 倍,但解码由 GPU 硬件完成,运行时开销相同

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 扩展支持。

补充:ASTC 由 ARM 开发、并由 Khronos Group 完成标准化,在 iOS(A8 以后)、Android(多数 Adreno/Mali GPU)与 Nintendo Switch 上获得广泛支持,已成为移动游戏开发的事实标准。它支持 1-4 个通道,并同时覆盖 LDR(8 位)与 HDR(16 位浮点),因此彩色纹理、法线贴图、遮罩等用途可用同一种格式承载。

  • 可变块尺寸:从 4x4 到 12x12 共 14 种块尺寸可选,能按品质需求精细控制
  • 5x5(5.12bpp)适合一般角色纹理与小道具,6x6(3.56bpp)适合背景与地形
  • Unity 中通过 TextureImporter 的设置指定 ASTC 块尺寸,Unreal 则在 Texture Compression Settings 中选择 ASTC 配置
  • 在构建流水线中集成 astcenc(ARM 官方编码器)即可进行高品质的离线编码

容器格式 - 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/纹理),不影响加载性能
  • 显著减少游戏安装包大小(无需为每个平台存储不同格式)

补充:容器格式决定压缩数据如何被打包与解析。DDS(DirectDraw Surface)是 DirectX/Windows 的标准容器,头部仅 128 字节,解析速度快,并可通过 DX10 扩展头支持 BC6H/BC7。KTX2 覆盖 ASTC、ETC2 与 BCn 全系列,并支持 Basis Universal 的超级压缩(Supercompression),最适合跨平台开发。

Basis Universal(.basis)由 Binomial 开发,可在运行时转码:ETC1S 模式先把图像压成 ETC1 兼容的中间表示,再按目标 GPU 转码;UASTC 模式使用 ASTC 4x4 兼容的高品质中间表示,可快速转码为 BC7 或 ASTC。代价是文件体积比各原生格式大 10-25%,但不再需要为每个平台准备单独的文件。

面向 Web 的 glTF 三维模型已把 KTX2 与 Basis Universal 作为标准选项,Three.js 与 Babylon.js 均提供原生支持。

平台特定的最佳格式选择

不同游戏平台的 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 作为源格式,构建时或运行时转码为目标平台格式。或在构建流水线中为每个平台生成对应格式的资源包。

补充:如果选择的格式不被目标平台 GPU 硬件支持,就会退化为 CPU 解码,性能大幅下降。因此需要按平台分别指定:

  • PC(Windows/DirectX 12):彩色用 BC7、法线贴图用 BC5、HDR 用 BC6H、灰度用 BC4。Linux/macOS 部分环境也支持 ASTC
  • PlayStation 5:以 BC7 为基础,使用专有的 GNF 容器格式
  • Xbox Series X/S:BC7 加上 Xbox 专有的 BCPack 追加压缩层
  • Nintendo Switch:推荐 ASTC,Tegra X1 也支持 BC7
  • iOS(A8 以后):以 ASTC 为标准,PVRTC 已不推荐(A15 以后仅推荐 ASTC)
  • Android:ASTC(Adreno 4xx 以后、Mali-T760 以后),并按目标 GPU 转换为 BC7/ASTC/ETC2

多平台开发的最佳实践:源资源以未压缩形式(PNG/TGA/EXR)管理,在构建流水线中转换为各平台的最优格式;在 Unity 的 Texture Import Settings 或 Unreal 的 Texture Compression Settings 中定义分平台设置;并把 texconv(DirectX)、astcenc(ARM)、basisu(Basis Universal)集成到 CI/CD 流水线中。

纹理图集与流式加载架构设计

大型游戏需要管理数千张纹理,图集打包和流式加载是性能优化的关键。

纹理图集(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 系统

补充:纹理图集与流式加载是减少绘制调用和提升 VRAM 效率的两大手段。图集可减少 GPU 的状态切换(纹理绑定),从而把绘制调用批处理;推荐尺寸一般为 2,048 × 2,048 或 4,096 × 4,096,尺寸不一致时可改用 TextureArray,或把各纹理对齐到 2 的幂。

纹理流式加载(Virtual Texturing)的要点:

  • 目的:当整个游戏的纹理无法全部放入显存时(AAA 级作品的纹理数据可达 20-50GB),只动态加载卸载需要的部分
  • Mip-Tail Streaming:低分辨率的 mip 层级(mip tail)常驻显存,高分辨率层级按相机距离流式加载
  • Sparse/Virtual Textures:使用 DirectX 12 的 Tiled Resources 或 Vulkan 的 Sparse Binding,只把巨大纹理的一部分映射到物理内存

实例:Unreal Engine 5 的 Virtual Texture Streaming 把 16K 纹理切分为 128 × 128 的图块,仅对可见图块进行流式加载,从而在维持观感品质的同时把 VRAM 占用减少 40-60%。

相关文章

深入图像压缩算法 - DCT、小波变换与预测编码

深入解析图像压缩的核心算法,包括 JPEG 的 DCT 变换、JPEG 2000 的小波变换,以及 AV1/HEVC 的预测编码技术。

图像格式对比 - JPEG/PNG/WebP/AVIF/GIF/BMP 的特性与适用场景

全面对比主流图像格式的特性、压缩效率和适用场景。从传统格式到新一代格式,提供基于用途的最佳选择指南。

纹理合成算法与应用 - 从基于块的方法到深度学习

全面解析纹理合成技术,从像素级方法到基于块的拼接、Gram 矩阵统计方法和 GAN 生成,涵盖实用工具和工作流。

WebGL 实时图像特效 - 从 Shader 基础到生产应用

使用 WebGL 实现实时图像特效的完整指南。涵盖 GPU 并行处理基础、色彩校正、模糊效果、扭曲特效及性能优化。

无损压缩与有损压缩对比 - 图像压缩方式选择指南

深入对比 PNG 无损压缩与 JPEG 有损压缩的算法原理、文件大小差异和适用场景。附带压缩率实测数据,帮助你为照片、图标和 Web 图像选择最佳方案。

图像格式发展史 - 从 BMP 到 AVIF 的 40 年演进

回顾图像格式 40 年的发展历程。从 BMP 和 GIF 的诞生到 AVIF 和 JPEG XL 的前沿,了解每种格式诞生的背景和技术突破。

相关术语