NVIDIA 卡上不同的 OpenGL 帧缓冲区 RGBA 值

Posted

技术标签:

【中文标题】NVIDIA 卡上不同的 OpenGL 帧缓冲区 RGBA 值【英文标题】:Different OpenGL Framebuffer RGBA values on NVIDIA cards 【发布时间】:2021-06-16 10:57:38 【问题描述】:

我正在尝试实现一种颜色选择算法,因此我在不同的帧缓冲区上用唯一颜色渲染我的实体,因此我可以查询鼠标所在像素上的帧缓冲区(使用 glReadPixels)并选择下面的实体鼠标光标。 这在我的集成 Intel HD Graphics 4600 上运行良好。我能够读回我在 GPU 上发送的确切值。 但是使用我的 Nvidia GTX 860M 运行应用程序,结果并不一致。一些随机像素具有原始颜色,但大多数像素的颜色略有改变。 同样的事情发生在另一台配备 Geforce 8600 GT 的计算机上。 我尝试使用 NSight Graphics 运行它,它允许我查看纹理的内存。 箭头指向正确的像素颜色。我希望每个像素都具有相同的颜色。

我用这个联合来创造一种独特的颜色......

union u_picking_color 
    struct s_entity *ep;
    glm::vec3 color;
;

然后我像这样查询帧缓冲区:

struct s_entity *Renderer::GetEntity(int x, int y) 
    union u_picking_color picking_color =  0 ;
    m_picking_fbo.SetReadTarget();
    glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT, &picking_color.color);
    return picking_color.ep;

以下是用于创建帧缓冲区的 API 调用:


glGenFramebuffers(1, &m_frameBufferId);
glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferId);
glGenTextures(1, &m_colorTextureId);
glBindTexture(GL_TEXTURE_2D, m_colorTextureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorTextureId, 0);
glGenTextures(1, &m_depthTextureId);
glBindTexture(GL_TEXTURE_2D, m_depthTextureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTextureId, 0);

此外,这里是用于在帧缓冲区上绘制的着色器。它们不会改变颜色。他们只通过管道传递它。

顶点:

#version 330 core

layout(location = 0) in vec3 v_Position;
//layout(location = 1) in vec3 v_Normal;
//layout(location = 2) in vec4 v_Color;
layout(location = 3) in vec3 v_PickingColor;

out vec4 color;
uniform mat4 u_ViewProjection;

void main()

    color = vec4(v_PickingColor, 1);
    gl_Position = u_ViewProjection * vec4(v_Position.x, v_Position.y, v_Position.z, 1.0f);

片段:

#version 330 core

out vec4 fragColor;

in vec4 color;

void main()
   
    fragColor = color;

我尝试禁用 GL_BLEND 和 GL_DITHER,但没有成功。

【问题讨论】:

【参考方案1】:

事实证明,即使我对每个顶点使用相同的颜色,我也应该在着色器上使用“flat”关键字来防止插值并避免精度错误。

顶点着色器:

flat out vec4 color;

片段着色器:

flat in vec4 color;

【讨论】:

以上是关于NVIDIA 卡上不同的 OpenGL 帧缓冲区 RGBA 值的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL - 在 NVIDIA 卡上渲染到纹理时出现 FBO 黑屏

Intel和Nvidia之间的OpenGL fbo blitting不一致

是否可以在 opengl 中从 2 个不同的线程渲染 2 个不同的帧缓冲区对象?

OpenGL 2 和 Primusrun 在单个缓冲区上无显示(透明窗口)

帧缓冲对象支持

Nvidia显卡上的阴影粉刺