考虑下面的代码。imageDataf是一个浮点型*。实际上,正如代码所示,它由光线跟踪器创建的float4值组成。当然,颜色值是在线性空间中,我需要他们在屏幕上输出伽马校正。所以我可以做的是一个简单的for循环,伽马校正为2.2 (参见for loop)。此外,我可以使用GL_FRAMEBUFFER_SRGB_EXT,它的工作几乎是正确的,但有“条带”问题。

左边是使用GL_FRAMEBUFFER_SRGB_EXT,右边是手动gamma校正。右边的图片看起来很完美。在一些监视器上发现它可能会有一些困难。有谁知道如何解决这个问题吗?我想做“免费”的伽马校正,因为CPU版本使GUI有点滞后。请注意,实际的光线跟踪是在另一个线程中使用GPU(optix)完成的,所以实际上它在渲染性能上也差不多快。
GLboolean sRGB = GL_FALSE;
glGetBooleanv( GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &sRGB );
if (sRGB) {
//glEnable(GL_FRAMEBUFFER_SRGB_EXT);
}
for(int i = 0; i < 768*768*4; i++)
{
imageDataf[i] = (float)powf(imageDataf[i], 1.0f/2.2f);
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 8);
glDrawPixels( static_cast<GLsizei>( buffer_width ), static_cast<GLsizei>( buffer_height ),
GL_RGBA, GL_FLOAT, (GLvoid*)imageDataf);
//glDisable(GL_FRAMEBUFFER_SRGB_EXT);发布于 2013-04-01 21:57:33
启用GL_FRAMEBUFFER_SRGB时,这意味着OpenGL将假定片段的颜色在线性色彩空间中。因此,当它将它们写入sRGB格式的图像时,它会在内部将它们从线性转换为sRGB。除了..。你的像素不是线性的。您已经将它们转换为非线性色彩空间。
但是,我将假定您只是忘记了其中的一条if语句。我将假设如果帧缓冲区支持sRGB,您可以跳过循环,直接上传数据。因此,我将会解释为什么你会变得有条带。
因为您请求的OpenGL操作执行以下操作,所以您将获得条带化。对于您指定的每种颜色:
步骤1-3都来自于glDrawPixels的使用。你的问题是第二步,你想让你的浮点值保持浮点数。然而,您坚持使用固定函数管道(即:glDrawPixels),它强制从浮点型转换为无符号规范化整数。
如果将数据上载到浮点纹理,并使用适当的碎片着色器来渲染此纹理(即使只是一个简单的gl_FragColor = texture(tex, texCoord);着色器),就可以了。着色器管道使用浮点数学,而不是整数数学。所以不会发生这样的转换。
简而言之:停止使用glDrawPixels。
https://stackoverflow.com/questions/15743884
复制相似问题