OpenGL包装规范
我正在试图理解使用OpenGL包装规范,opengl,Opengl,我正在试图理解使用GL_INT_2_10_10_REV作为我的数据V.S.GLbyte的正常值之间的区别。目前,我正在将法线加载到glm::vec4中,并将其打包如下: int32_t floatToSignedNormalizedByte(float x, float y, float z, float w) { int32_t result = 0; const int16_t maxValue = static_cast<int16_t>(std::numeri
GL_INT_2_10_10_REV
作为我的数据V.S.GLbyte
的正常值之间的区别。目前,我正在将法线加载到glm::vec4
中,并将其打包如下:
int32_t floatToSignedNormalizedByte(float x, float y, float z, float w)
{
int32_t result = 0;
const int16_t maxValue = static_cast<int16_t>(std::numeric_limits<int8_t>::max());
const int16_t negativeValueScale = maxValue + 1;
result |= static_cast<int8_t>(x < 0 ? x * negativeValueScale : x * maxValue);
result |= static_cast<int8_t>(y < 0 ? y * negativeValueScale : y * maxValue) << 8;
result |= static_cast<int8_t>(z < 0 ? z * negativeValueScale : z * maxValue) << 16;
result |= static_cast<int8_t>(w < 0 ? w * negativeValueScale : w * maxValue) << 24;
return result;
}
我的问题是,考虑到我打包的方式,我是否应该使用GL_INT_2_10_10_REV
作为我的类型(替换GL_字节)?我理解使用GL_INT_2_10_10_10_REV
意味着每个组件获得10位而不是8位,这很好,因为实际上我只需要xyz组件。哪一个更好,为什么?如果我使用GL_INT_2_10_10_10_REV
,我猜组件计数仍然是4?为什么
正如您所说,使用10_10_10_2将为每个有意义的分量(xyz)提供10位,同时为w分量保留2位,而w分量对法向量没有用处。对于10位,您有x、y和z的2^10
可能的离散值,而不是8位提供的2^8
值。因此,这将为法线和更平滑的渐变提供更精确的值。您也可以使用浮点值,但这些值需要更多内存,而且速度可能较慢。这回答了“我为什么要这样做”部分
怎么
至于“how”,您当前的packing函数将每个float
转换为8位整数。您需要对此进行更改,以将x、y和z分量转换为10位整数,并将这些位与01
一起打包为最后2位(w分量)。REV
版本只允许您以相反的顺序(wzyx)指定组件
有关GL_INT_2_10_10_10_REV
顶点格式的更多信息
OpenGL规范的表10.3和表10.4描述了这些组件如何在32位字中布局:
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
| w | z | y | x |
Table 10.3: Packed component layout for non-BGRA formats. Bit numbers are indicated for each component.
UNSIGNED_INT_2_10_10_10_REV:
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
| w | x | y | z |
Table 10.4: Packed component layout for BGRA format. Bit numbers are indicated for each component.
如您所见,此顶点格式中有4个组件
如果您想了解更多背景信息,还可能会找到有趣的阅读说明:
两种新的顶点属性数据格式:有符号的2.10.10.10和无符号的2.10.10.10顶点数据格式。这些顶点数据格式描述了一个4分量流,可用于以量化形式存储法线或其他属性。法线、切线、副法线和其他顶点属性通常可以以较低的精度指定,而不会引入明显的瑕疵,从而减少它们所消耗的内存量和内存带宽
“降低精度”指的是使用10位整数,而不是法线的半浮点数(16位)或浮点数(32位)。每个顶点具有更少的位可以提供更好的性能,因为顶点组装阶段需要更少的内存带宽
这个问题还有相关信息:@Nicolas,法线不应该签名吗?阅读规范,对于有符号规范化整数,我可以选择8位的范围[-128127],或者[-127127]。有人说第一个更适合顶点,而第二个更适合纹理。我知道第二个可以精确地表示0,而第一个不能。我认为这不是一个大问题。我做错了什么?请帮帮我:)好的,我只是在自言自语:(我删除了旧评论,因为它是错误的。但是,我发现了另一个潜在的问题:。但除此之外,我不确定你的问题到底是什么。你是在问如何使用2_10_10_10作为一种格式,还是你应该还是什么?@NicolBolas,我是在问如何使用2_10_10_10,如果我应该将其用于正常值,以及如何正确打包。)我发现如果没有
REV
标志,很难知道包装的顺序。对于我包装的方式,顺序应该是什么?REV
清楚地表明xyzw应该包装为->wzyx,从高位到低位(从左到右).所以类型应该是GL_INT_2_10_10_10_REV,组件计数仍然是4?如果我想继续使用2^8
packing怎么办?它们的顺序应该相同,w是最高位,x是最低位吗?
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
| w | z | y | x |
Table 10.3: Packed component layout for non-BGRA formats. Bit numbers are indicated for each component.
UNSIGNED_INT_2_10_10_10_REV:
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
| w | x | y | z |
Table 10.4: Packed component layout for BGRA format. Bit numbers are indicated for each component.