顶点属性 - 使用 short 而不是 float 作为顶点位置

Vertex attributes - using short instead of float for vertex positions

目前我有以下设置,目前运行良好。

struct Vertex {
    glm::vec3 position;
    glm::vec3 normal;
    glm::vec2 texCoord;
}
std::vector<Vertex> vertices;

顶点属性:

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(Vertex, Vertex::position)); 
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(Vertex, Vertex::normal));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) offsetof(Vertex, Vertex::texCoord));

现在我想通过将顶点属性从浮动更改为短来提高我的性能。 我试着从顶点位置开始。

OpenGL's Vertex Specification Best Practices 告诉我这个:

Positions [...] To do this, you rearrange your model space data so that all positions are packed in a [-1, 1] box around the origin. You do that by finding the min/max values in XYZ among all positions. Then you subtract the center point of the min/max box from all vertex positions; followed by scaling all of the positions by half the width/height/depth of the min/max box. You need to keep the center point and scaling factors around. When you build your model-to-view matrix (or model-to-whatever matrix), you need to apply the center point offset and scale at the top of the transform stack (so at the end, right before you draw).

我也看了这个Thread

这就是为什么我添加了这个预处理步骤,将所有顶点映射到 [-1,1]

for (auto& v : vertices) {
    v.position = (v.position - center) * halfAxisLengths;
}

并在顶点着色器中重新调整它

vec4 rescaledPos = vec4(in_pos, 1.0) * vec4(halfAxisLengths, 1.0) + vec4(center, 0.0);
gl_Position = P * V * M * rescaledPos;

我的顶点属性使用 GL_SHORT 而不是 GL_FLOAT,并且规范化设置为 GL_TRUE:

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_SHORT, GL_TRUE, sizeof(Vertex), (void*) offsetof(Vertex, Vertex::position));

结果我得到了一堆混乱的三角形,但我的模型没有增加 fps。

这是将顶点属性设置为短的正确方法吗?

或者我必须更改完整的 Vertex 结构吗? 如果是,最好的方法是什么(带短裤的 glm 向量?)。

一个工作示例会很棒,我找不到。

Or do I have to change my complete Vertex structure?

是的,OpenGL 不会神奇地为您进行转换。但是,如果性能是您的目标……

Now I want to increase my performance by changing the vertex attributes to from float to short.

这实际上会影响性能。 GPU 针对将矢量处理为浮点值进行了优化。这反过来会影响内存接口,该接口旨在为 32 位对齐访问提供最佳性能。通过提交 16 位短整数,您将强制当前 GPU 行执行次优内存访问和中间转换步骤。

如果性能是您的目标,请坚持使用单精度浮点数。如果您不相信我:对其进行基准测试。

我调整了顶点缓冲区的数据结构:

struct newVertex {
    GLshort position[4]; // for GL_SHORT
    GLint normal; // for GL_INT_2_10_10_10_REV
    GLshort texCoord[2]; // for GL_SHORT
};

因此,我的性能提高了约 20%。