【问题标题】:How to get a floating-point color from GLSL如何从 GLSL 获取浮点颜色
【发布时间】:2014-04-28 08:59:20
【问题描述】:

我目前面临一个与 OpenGL 管道和着色器使用密切相关的问题。

确实,我从事一个项目,其中一个步骤包括从我们使用 OpenGL 生成的图像中读取像素,并尽可能准确:我的意思是,我不想读取整数,而是读取浮点数. (因此,我不想读取像素的值 (134, 208, 108),而是想要获得类似 (134.180, 207.686, 108.413) 的值。)

对于这个项目,我使用了顶点着色器和片段着色器来渲染我的场景。我假设片段着色器计算和返回的颜色是属于“连续” [0, 1] 内部的 4 个浮点数(每个 RGBA 分量一个)的向量。但是,我怎样才能在我的 C++ 文件中得到它?有办法吗?

我想在将我的场景渲染到缓冲区后调用glReadPixels() 函数,方法是将格式参数设置为GL_RGBA,并将像素数据的数据类型设置为GL_FLOAT。但我感觉与我们读取的像素相关联的值同时已经被转换为整数,因为我最终得到的浮点数对应于区间 [0, 255] 被钳制为 [0, 1],精度没有任何提高。仔细查看 OpenGL 规范强化了这个想法:我认为在渲染我的场景和调用glReadPixels() 之间确实存在某种转换。

您对我实现目标的方式有任何想法吗?

【问题讨论】:

  • glClampColor (...),可用于修改从颜色缓冲区读取的默认行为。虽然在大多数情况下它并不是特别有用,但您真正想要的首先是绘制到浮点颜色缓冲区中。
  • 亲爱的安东,非常感谢您的回答!但是,恐怕这个提示不起作用。我将clamp 参数设置为GL_TRUEGL_FALSE,我得到相同的结果,每个通道只有256 个可能的值。你有别的想法吗?
  • 您是否正在渲染到默认帧缓冲区(即设备的后台缓冲区)。如果是这样,则颜色可能会在每个通道中存储 1 个字节。您需要制作自己的帧缓冲区(参见glGenFramebuffersglBindFramebuffer 等)并将浮点纹理绑定到它(使用glFramebufferTexture2D)。
  • @GuyRT:你是对的!使用双向纹理是打破这种束缚的好方法。现在它起作用了。非常感谢!!

标签: opengl glsl


【解决方案1】:

片段着色器返回的 GL_RGBA 格式以 8 位整数存储像素分量。您应该使用浮点格式,例如 GL_RGBA16F 或 GL_RGBA32F,其中 16 和 32 是每个组件的深度。

【讨论】:

  • 片段着色器总是输出浮点组件。实际上只有在混合之后才会将事物转换为无符号归一化(定点)格式,例如GL_RGBA 进行存储。
  • 非常感谢您的回答,但除了GL_RGBA 和其他之外,没有GL_RGBA16F 接受glReadPixels 的参数,只有GL_STENCIL_INDEXGL_DEPTH_COMPONENTGL_DEPTH_STENCIL。但是前三个和最后一个没有任何关系,是吗?
  • 它们不应该被传递给 glReadPixels。关注 GuyRT 评论。他提到的“浮点纹理”只是我的答案中使用其中一种浮点格式生成的纹理。
  • 你和 GuyRT 对纹理和 GL_RGBA32F 格式的看法是正确的。现在它起作用了。非常感谢!!
猜你喜欢
  • 1970-01-01
  • 2013-08-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-17
  • 1970-01-01
  • 2012-02-21
相关资源
最近更新 更多