我正在用C++编程OpenGL渲染器。我希望它尽可能高效,并且每个顶点/普通/ UV tex坐标/切线/等都要占用尽可能少的内存。我正在使用索引,线条和粉丝。我认为32位浮点数不是必须的,16位浮点数应该没问题,至少对于像法线和UV这样的一些浮点。我似乎无法在任何地方找到任何这方面的例子。我可以找到关于“GL_HALF_FLOAT”的讨论,但没有真正的例子。我在正确的轨道上吗?或者这不值得寻找?如果有人知道这样的例子,他们可以发送一个源代码的链接?“GL_HALF_FLOAT”使用OpenGL渲染和GLSL
2
A
回答
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的转换,要么使用其他人编写的代码。
以下有关半浮点转换的资源来自快速搜索。我与任何人没有亲身经历,你应该做你自己的搜索,找到一个最适合你的需求:
- 从英特尔有趣的文章,解释可能的性能优势:https://software.intel.com/en-us/articles/performance-benefits-of-half-precision-floats。这也提到英特尔处理器有转换的指令(例如有一个内部的
_mm256_cvtps_ph
从float转换为half-float)。 - 用于半浮点操作和转换的开源库:http://half.sourceforge.net/。
- gcc文档说它支持ARM目标的半浮点类型(
__fp16
)。
相关问题
- 1. 渲染到QOpenGLFramebufferObject GL_HALF_FLOAT
- 2. 在OpenGL和GLSL中的点渲染
- 3. 渲染使用OpenGL
- 4. OpenGL渲染不使用OpenCV的GLSL着色器
- 5. 使用OpenGL渲染错误
- 6. 使用Freetype和OpenGL渲染字体
- 7. 使用GLSL framebuffer渲染时出错
- 8. 渲染SVG支持OpenGL(和OpenGL ES)
- 9. OpenGL渲染故障
- 10. Opengl渲染顺序
- 11. OpenGL全屏渲染
- 12. OpenGL停止渲染
- 13. OpenGL渲染纹理
- 14. 如何使用OpenGL ES渲染图像?
- 15. 使用webgl/opengl进行轮廓渲染
- 16. OpenGL:仅使用GL_POINTS渲染线条
- 17. OpenGL保存渲染供以后使用
- 18. Android:使用NDK进行OpenGL渲染
- 19. Win32 API渲染线程和OpenGL
- 20. Qt和OpenGL如何渲染PVR
- 21. QT Webkit和OpenGL渲染上下文
- 22. 结合画布和OpenGL ES渲染器?
- 23. onDrawFrame,requestRender和渲染线程? | OpenGL ES 2.0
- 24. OpenGL Viewer控制和渲染上下文
- 25. C#OpenTK GLSL尝试渲染时崩溃
- 26. opengl关闭屏幕渲染
- 27. OpenGL L系统渲染
- 28. OpenGL奇怪的渲染
- 29. OpenGL ES渲染到纹理
- 30. android opengl渲染垃圾
可以使用'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
@ AndonM.Coleman您可以在顶点缓冲区中使用'HALF_FLOAT'数据。当它到达着色器时,它当然会扩展到32位精度,但如果半浮点数对于坐标具有足够的精度,则仍可节省存储空间和带宽。 – 2015-02-06 04:49:32
@ReetoKoradi:我完全误解了这个问题,因为我的思想是在其他地方: - 我有点看到了标签,并认为他想改变GLSL中'float'的精度。是的,你完全正确 - 尽管因为半浮点数不是大多数语言的一部分,所以像glm(假设这是C++)将不得不填充该角色。 – 2015-02-06 05:04:48