2015-02-06 194 views
2

我正在用C++编程OpenGL渲染器。我希望它尽可能高效,并且每个顶点/普通/ UV tex坐标/切线/等都要占用尽可能少的内存。我正在使用索引,线条和粉丝。我认为32位浮点数不是必须的,16位浮点数应该没问题,至少对于像法线和UV这样的一些浮点。我似乎无法在任何地方找到任何这方面的例子。我可以找到关于“GL_HALF_FLOAT”的讨论,但没有真正的例子。我在正确的轨道上吗?或者这不值得寻找?如果有人知道这样的例子,他们可以发送一个源代码的链接?“GL_HALF_FLOAT”使用OpenGL渲染和GLSL

+1

可以使用'uint'数据类型打包和解压缩2个半浮点数。但是您将要在GLSL中获得的最小数据类型是32位。有关更多详细信息,请参阅['uint packHalf2x16(\t vec2 v)'](https://www.opengl.org/sdk/docs/man4/html/packHalf2x16.xhtml)。 – 2015-02-06 04:32:59

+0

@ AndonM.Coleman您可以在顶点缓冲区中使用'HALF_FLOAT'数据。当它到达着色器时,它当然会扩展到32位精度,但如果半浮点数对于坐标具有足够的精度,则仍可节省存储空间和带宽。 – 2015-02-06 04:49:32

+0

@ReetoKoradi:我完全误解了这个问题,因为我的思想是在其他地方: - 我有点看到了标签,并认为他想改变GLSL中'float'的精度。是的,你完全正确 - 尽管因为半浮点数不是大多数语言的一部分,所以像glm(假设这是C++)将不得不填充该角色。 – 2015-02-06 05:04:48

回答

4

在完整的OpenGL中(与OpenGL ES不同),着色器代码始终使用32位浮点运算。不过,从OpenGL 3.0开始,支持将顶点数据指定为半浮点数。如果精度足够满足您的需求,这可以减少顶点数据的内存使用量,并减少顶点提取所需的带宽。

请记住,半浮点的精度只有约3-4个十进制数字。所以准确度真的非常有限。

至于如何使用它们,这是非常简单的。如果您有指向半浮点值的指针,则使用glBufferData()glBufferSubData()将它们存储在VBO中,就像您对其他类型的值一样。然后,glVertexAttribPointer()呼叫看起来像这样,使用具有3个分量的属性,例如:

glVertexAttribPointer(loc, 3, GL_HALF_FLOAT, GL_FALSE, 0); 

数据本身的格式在ARB_texture_float扩展中定义。虽然它没有正式命名,但它至少非常类似于IEEE 754-2008格式。我之前编写了基于Wikipedia格式描述的转换代码,并且它对OpenGL的使用效果很好。

大多数语言都没有内置的半浮点类型。所以你要么写几行代码来完成从float到half-float的转换,要么使用其他人编写的代码。

以下有关半浮点转换的资源来自快速搜索。我与任何人没有亲身经历,你应该做你自己的搜索,找到一个最适合你的需求: