OpenGL打包正常 [英] OpenGL packing normal

查看:134
本文介绍了OpenGL打包正常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解使用GL_INT_2_10_10_10_REV作为正常数据V.S. GLbyte.目前,我正在将法线加载到glm::vec4中,并像这样打包它:

I am trying to understand the difference between using GL_INT_2_10_10_10_REV for the normal of my data V.S. GLbyte . Currently I'm loading my normals into a glm::vec4 and I'm packing it like so:

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;
}

在打包常态的情况下,我会打电话给

With the packed normal, I would then call:

//Location, component count, type, normalized, stride, offset
glVertexAttribPointer(location, 4, GL_BYTE, true, format.getVertexSize(),  format.getFieldOffset(field, dataBasePtr));

我的问题是,考虑到我打包普通文件的方式,我应该使用GL_INT_2_10_10_10_REV作为我的类型(替换GL_BYTE)吗?我知道使用GL_INT_2_10_10_10_REV意味着每个组件获取10位而不是8位,这很好,因为实际上我只需要xyz组件.哪一个更好,为什么?如果使用GL_INT_2_10_10_10_REV,我猜组件数仍为4?

My question is, given the way I'm packing my normal, should I be using GL_INT_2_10_10_10_REV as my type (replacing GL_BYTE)? I understand using GL_INT_2_10_10_10_REV means each component gets 10bits instead of 8 and that's fine since really I only need the xyz component. Which one is better and why? If I use GL_INT_2_10_10_10_REV, I am guessing component count is still 4?

推荐答案

为什么

正如您所说,使用10_10_10_2将为您每个有意义的分量(xyz)提供10位,而为w分量保留2位,这对于正常向量是无用的.如果使用10位,则x,y和z可能有2^10个离散值,而不是8位提供的2^8值.因此,这将为您提供更准确的法线值和更平滑的渐变.您也可以使用浮点值,但是这些值将需要更多的内存,并且速度可能会更慢.这回答了我为什么要这样做"部分.

Why

As you said, using 10_10_10_2 will give you 10 bits per meaningful component (xyz) while leaving 2 bits for the w component which is useless for normal vectors. With 10 bits you have 2^10 possible discrete values for x, y and z instead of the 2^8 values provided by 8 bits. This will therefore give you more accurate values for the normals and smoother gradients. You could also use floating-point values, but these would require more memory and would likely be slower. This answers the "why should I do this" part.

至于方式",您当前的打包功能会将每个float转换为8位整数.您需要对此进行更改,以将x,y和z分量转换为10位整数,并将这些位与01打包在一起作为最后2位(w分量). REV版本仅允许您以相反的顺序(wzyx)指定组件.

As for the "how", your current packing function transforms each float into an 8 bit integer. You would need to change this to transform the x, y and z components in 10 bit integers and pack those bits together with 01 as the last 2 bits (the w component). The REV version simply allows you to specify the components in the reverse order (wzyx).

OpenGL规范的表10.3和10.4描述了如何用32位字布置这些组件:

Tables 10.3 and 10.4 of the OpenGL specification describe how these components are laid out in a 32-bit word:

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个组成部分.

As you can see, there are 4 components in this vertex format.

您可能还会找到 GL_ARB_vertex_type_2_10_10_10_rev 的规范如果您想要更多背景知识,请读有趣的文章:

You might also find the specification of GL_ARB_vertex_type_2_10_10_10_rev an interesting read if you want more background:

两种新的顶点属性数据格式:带符号的2.10.10.10和无符号的2.10.10.10顶点数据格式.这些顶点数据格式描述了4分量流,可用于以量化形式存储法线或其他属性.通常可以以降低的精度指定法线,切线,双法线和其他顶点属性,而不会引入明显的伪像,从而减少了它们占用的内存量和内存带宽.

Two new vertex attribute data formats: a signed 2.10.10.10 and an unsigned 2.10.10.10 vertex data format. These vertex data formats describe a 4 component stream which can be used to store normals or other attributes in a quantized form. Normals, tangents, binormals and other vertex attributes can often be specified at reduced precision without introducing noticeable artifacts, reducing the amount of memory and memory bandwidth they consume.

降低的精度"是指使用10位整数而不是法线的一半float(16位)或float(32位)值.每个顶点具有更少的位可以提供更好的性能,因为顶点组装阶段需要更少的内存带宽.

The "reduced precision" refers to using 10 bit integers instead of half float (16 bits) or float (32 bits) values for normals. Having fewer bits per vertex can provide better performance because the vertex assembly stage needs less memory bandwidth.

此问题还具有相关信息:使用GL_INT_2_10_10_10_REV在glVertexAttribPointer()

This question also has relevant info: Using GL_INT_2_10_10_10_REV in glVertexAttribPointer()

这篇关于OpenGL打包正常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆