OpenGL浮点精度
Posted
技术标签:
【中文标题】OpenGL浮点精度【英文标题】:OpenGL floating point precision 【发布时间】:2020-01-14 19:01:35 【问题描述】:我正在开展一个从旧版/即时 OpenGL 迁移到现代 OpenGL(核心配置文件)的项目。在传统的 OpenGL 实现中,我们使用了双精度,即我们在 glVertexPointer
中使用了 GL_DOUBLE
,我们使用了 glLoadMatrixd
等。但是,在现代 OpenGL 中,只有 OpenGL/GLSL 4.0+ 支持双精度。
旧的 OpenGL 如何支持双精度,而新的 OpenGL 不支持? 传统 OpenGL 如何处理双精度,而大多数显卡甚至不支持双精度?
我在互联网上找不到任何信息,或者某些答案太旧了。
目前的显卡支持双精度吗?我应该使用 OpenGL 4.0 吗?
【问题讨论】:
如果GL_DOUBLE
在几乎所有情况下实际上都没有等同于 C++ double
,我会感到非常惊讶。
我不确定,但我希望旧显卡默认使用半浮动。并且 GL_DOUBLE 意味着常规浮动。但我只是推测。显卡支持double
,但它们往往拥有更少的内核来执行双重计算,这使得它几乎毫无用处,因为性能会受到巨大影响。
@JesperJuhl GL_DOUBLE
应该等于 c++ double
,因为旧版 OpenGL 与 C++ double
一起使用。但是,现代 OpenGL(不是 OpenGL 4.0+)没有用于双精度的 API,即 glUniform
不接受双精度,并且您无法在着色器中定义双精度。
【参考方案1】:
旧的 OpenGL 如何支持双精度,而新的 OpenGL 不支持?传统 OpenGL 如何处理双精度,而大多数显卡甚至不支持双精度?
它不是你想的那样。您可以使用双精度作为顶点属性并不意味着(并且从未这样做过)GL 实现将以该精度进行计算——GPU 从未这样做过。在任何情况下,数据都会转换为单精度。矩阵也是如此——在旧版 GL 中,发送到 GPU 的矩阵永远不会是双精度的,无论您在指定 CPU 端数据时使用的是 d
还是 f
后缀。
在更新的 GPU 中,着色器内核提供了双精度,而现代 GL 4.x 允许您第一次使用它。
另外请注意,许多实际消费级 GPU 的双精度比都非常低,例如 FP32 性能的 1/32,因此您最好在使用之前三思而后行。对于图形,您很少需要它。而且您之前的代码与旧版 GL 一起使用的事实证明您不需要精度。
【讨论】:
感谢您的回答!所以即使我用glm::dvec3
顶点调用glVertexPointer
,显卡内部也使用单精度?
是的!为此,您需要 GL4.something 和 glVertexAttirbLPointer
(注意函数名称中的 L
,“L”代表“double”)
@TaoChen:“所以即使我用 glm::dvec3 顶点调用 glVertexPointer,显卡内部也使用单精度?” 不仅如此。如果您尝试这样做,系统基本上必须在 CPU 上 读取您的顶点数据并将双精度数转换为浮点数,因为硬件实际上无法读取它们。这样做会影响你的表现。
"对于图形,您很少需要它。" 实际上,您将使用它的最明显的地方(VS 中的位置)实际上并没有帮助,因为 @987654327 @ 是单精度向量。即使不是,使用它的硬件肯定也无法处理双精度值。深度缓冲区也不能。以上是关于OpenGL浮点精度的主要内容,如果未能解决你的问题,请参考以下文章
转换浮点数组中的 blend 或 obj 文件以在 OpenGL 中绘图
OpenGL 中的 2D 绘图:在原始尺寸下具有像素精度的线性过滤
是否可以将 Mat4 作为 rust 'glam' crate 中的浮点指针传递给 Opengl 调用 gl::UniformMatrix4fv?