简体   繁体   English

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

[英]Vertex attributes - using short instead of float for vertex positions

Currently I have following setup which is working fine for far. 目前,我有以下设置可以正常工作。

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

The Vertex-Attributes: 顶点属性:

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

Now I want to increase my performance by changing the vertex attributes to from float to short. 现在,我想通过将顶点属性从float更改为short来提高性能。 I tried to start with the vertex positions. 我试图从顶点位置开始。

OpenGL's Vertex Specification Best Practices tells me this: OpenGL的“顶点规范最佳实践”告诉我:

Positions [...] To do this, you rearrange your model space data so that all positions are packed in a [-1, 1] box around the origin. 位置 [...]为此,您需要重新排列模型空间数据,以便将所有位置打包在原点周围的[-1,1]框中。 You do that by finding the min/max values in XYZ among all positions. 通过在所有位置中找到XYZ中的最小/最大值来做到这一点。 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). 构建模型到视图矩阵(或模型到所有矩阵)时,需要在变换堆栈的顶部(因此,在绘制之前,在最后)应用中心点偏移和缩放。

I also read this Thread . 我也阅读了这个主题

That's why I added this preprocessing step mapping all vertices to [-1,1] 因此,我添加了此预处理步骤,将所有顶点映射到[-1,1]

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

and recale it in the vertex-shader 并在顶点着色器中重新设置它

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

My vertex attribute using GL_SHORT instead of GL_FLOAT , and normalize set to GL_TRUE : 我的顶点属性使用GL_SHORT而不是GL_FLOAT ,并且规格化设置为GL_TRUE

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

As result I just get a chaos of triangles, but not my model with increased fps. 结果,我得到的只是一个混乱的三角形,但是我的模型却没有得到提高的fps。

Is this the correct way to set vertex attributes to short? 这是将顶点属性设置为short的正确方法吗?

Or do I have to change my complete Vertex structure? 还是我必须更改完整的顶点结构? If yes, what's the best way to do this (glm vectors with shorts?). 如果是,执行此操作的最佳方法是什么(带有短裤的glm向量?)。

An working example would be great, I couldn't find any. 一个有效的示例将是很棒的,我找不到任何示例。

I adjusted the data structure for the vertex buffer: 我调整了顶点缓冲区的数据结构:

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

As a result I get ~20% increased performance. 结果,我的性能提高了约20%。

Or do I have to change my complete Vertex structure? 还是我必须更改完整的顶点结构?

Yes, OpenGL will not magically do the conversion for you. 是的,OpenGL不会神奇地为您完成转换。 But then if performance is your goal… 但是,如果性能是您的目标……

Now I want to increase my performance by changing the vertex attributes to from float to short. 现在,我想通过将顶点属性从float更改为short来提高性能。

This would actually hurt performance. 这实际上会损害性能。 GPUs are optimized for processing vectors as floating point values. GPU已针对将向量作为浮点值进行了优化。 This in turn influences the memory interface, which is designed to give best performance for 32 bit aligned accesses. 这反过来会影响内存接口,该接口旨在为32位对齐的访问提供最佳性能。 Bysubmitting as 16 bit short integer you're forcing the current line of GPUs to perform suboptimal memory access and an intermediary conversion step. 通过提交16位短整数,您可以强制当前的GPU行执行次佳的内存访问和中间转换步骤。

If performance is your goal stick to single precision float. 如果您的目标是性能,则坚持单精度浮点数。 If you don't believe me: Benchmark it. 如果您不相信我:请进行基准测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM