学习纹理格式(DXGI_FORMAT 和 VkFormat)

目标

《图形API学习工程(11):使用纹理》中我学习了如何创建纹理,在创建时都指定了其格式:
在这里插入图片描述
在这里插入图片描述
对于DirectX,是DXGI_FORMAT
对于Vulkan,是VkFormat
(OpenGL也有类似的东西,随后讨论)

本篇的目标是——查阅资料并结合自己的思考,对纹理格式的相关内容进行学习与讨论,具体包括:

  • 讨论为何要使用和指定不同的纹理格式
  • 纹理格式中常见关键字的学习

讨论为何要指定纹理格式

在一开始,我并不理解为何要有不同的纹理格式,因为我知道显示器可以显示红绿蓝三种颜色的光分别有0~255级别,即8位二进制。那这样的话纹理中每个像素不就是最多用24位吗?如果加上alpha通道那不就是32位吗?为何还需要那么多纹理格式呢?

后来,我发现这种想法是很局限的。

导致格式不同的原因

在渲染时使用的纹理,并非都是所谓的 红、绿、蓝、Alpha四通道各8位 。还有其他格式的纹理被需要,原因有很多,至少在我的理解中有以下方面:

  • 并非所有的纹理都需要 红、绿、蓝、Alpha 这四个通道,比如有些纹理只需要其中一个通道即可完成它自己的任务。
  • 有些纹理需要存储的光的强度并不是8位能表示的。比如HDR(high-dynamic range)
  • 有些纹理使用压缩来减少自己的内存开销,压缩方式例如 block-compressionASTC
不同格式对应的位数

不同的纹理格式导致数据的大小不同。比如:

  • 如果一个通道使用8位的BYTE保存,那么对于每个像素:红、绿、蓝、Alpha四通道就是4x8=32位。
  • 如果一个通道使用32位的float保存,那么对于每个像素:红、绿、蓝、Alpha四通道就是4x32=128位。
  • 如果使用了压缩技术,则情况更复杂一些,总体数据的大小一定比压缩前更小。

而同样数据大小可能有多种格式与之对应。例如:

  • 对于每像素32位的大小。它既可能是“红、绿、蓝、Alpha四通道的BYTE”,也可能是“只有一个红通道的float

因此创建纹理时指定格式是必要的,否则GPU就不知道如何对纹理数据进行解读。

常见关键字

这些纹理格式的命名都使用了缩写,在DXGI_FORMATVkFormat之间也有相似的共用词语。
为了能更快明白一个纹理格式名字的含义,我想对其中常见的关键词进行总结。
(对于更权威与全面的解释还需要看DXGI_FORMATVkFormat官方文档)

RGBA

Red、Green、Blue、Alpha。红、绿、蓝再加上一般表示不透明度的Alpha通道。
例如:

  • R8G8B8A8表示红通道8位、绿通道8位、蓝通道8位、Alpha通道8位。
  • R8G8相比上者只有红通道和绿通道
_UNORM

Unsigned-Normalized-Integer。无符号型归一化的整数。
所谓“无符号”指的是没有负数,即全是正值。
所谓的“归一化”指的是,最终表示的值是0.0~1.0。例如假设这个整数是8位的即0~255,那么255对应1.0128大约对应0.5;假设这个整数是16位的,即0~65535,那么65535对应1.032768大约对应0.5

举例格式:

  • R8G8B8A8_UNORM表示红通道8位、绿通道8位、蓝通道8位、Alpha通道8位,且8位代表的是一个无符号型归一化的整数。
_FLOAT

浮点数。对于DirectX来说是 _FLOAT,对于Vulakn来说是 _SFLOAT,不过含义相同,后者的S意思是 “signed”,即有符号的,而DirectX中同样是有符号的。

DXGI_FORMAT文档中的说明:
在这里插入图片描述

  • 32位的浮点数使用 IEEE 754 单精度 的标准:1位符号、8位指数偏移、23位数值部分。
  • 16位的浮点数使用半精度(s10e5)的格式:1位符号、5位指数偏移、10位数值部分。

不过似乎在DXGI_FORMAT中也有既不是32位也不是16位的浮点数:
在这里插入图片描述
只是似乎比较少见。

_SNORM

Signed Normalized Integer。带符号的归一化的整数。

_UINT

Unsigned integer。无符号型的整数

_SINT

Signed Integer。带符号型的整数。

BC

block-compressed 型纹理压缩格式,详见:
Texture Block Compression in Direct3D 11 - Win32 apps | Microsoft Docs

ASTC

ASTC型纹理压缩格式,详见:
Using ASTC Texture Compression for Game Assets | NVIDIA Developer

OpenGL

而OpenGL在这方面似乎稍微繁琐一些,因为它指定纹理格式方面不是由一个东西决定的:
在这里插入图片描述
对于glTexImage2D这个函数,在《OpenGL红书》中有对相关参数较为权威的解释:
在这里插入图片描述
它指出:

  • internalformat指定了OpenGL应该怎样存储纹理中的数据。
  • formattype共同指定了初始数据的格式。随后OpenGL将根据这个格式来对数据进行解析并转换为internalformat

《OpenGL红书》的【TextureFormats】章节可以看到对所有格式的说明
在这里插入图片描述
(在这篇文章中也有讨论:《OpenGL ES 3.0 纹理格式介绍及有效的内部格式、格式、类型组合_阿飞的博客-CSDN博客》值得学习)

未来问题

  • _SRGB 这个关键字似乎很频繁出现,具体的意义是什么?

  • DXGI_FORMAT中的 _TYPELESS 的含义。

  • OpenGL纹理格式更深入的学习

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值