【问题标题】:OpenGL cannot read framebuffer attachment when there are only 3 components, but can read when there's 4 component当只有 3 个分量时 OpenGL 无法读取帧缓冲区附件,但当有 4 个分量时可以读取
【发布时间】:2023-02-07 11:23:19
【问题描述】:

我目前正在 OpenGL 中进行延迟渲染,目前正在尝试将位置和法线数据从几何通道传递到光照通道。

但是,任何非 GL_RGBA 类型的帧缓冲区附件在作为纹理读取时都会给出空值。我设法将其归结为这样一个事实,即任何不包含 4 个组件的帧缓冲区附件都无法正常工作。

我怎样才能解决这个问题?我错过了什么?

C++ 代码:

// Geometry Buffer
gbuffer::gbuffer(uint32_t _width, uint32_t _height) {
    // Create GL buffer.
    glCreateFramebuffers(1, &handle_);

    // Colour attachments.
    colour_attachments_.resize(num_gbuffer_attachments);
    colour_attachments_[gbuffer_position] = std::make_shared<texture_2d>("position", _width, _height, GL_RGB16F); // Only 3 components, does not work.
    colour_attachments_[gbuffer_normal] = std::make_shared<texture_2d>("normal", _width, _height, GL_RGB16F); // Only 3 components, does not work.
    colour_attachments_[gbuffer_albedo] = std::make_shared<texture_2d>("albedo_colour", _width, _height, GL_RGBA8); // 4 components, no problem.
    colour_attachments_[gbuffer_specular] = std::make_shared<texture_2d>("specular_colour", _width, _height, GL_RGBA8);  // 4 components, no problem.
    colour_attachments_[gbuffer_gloss] = std::make_shared<texture_2d>("gloss", _width, _height, GL_R32F); // Only 1 component, does not work.
    for (auto i = 0; i < colour_attachments_.size(); ++i) {
        glNamedFramebufferTexture(handle_, GL_COLOR_ATTACHMENT0 + i, colour_attachments_[i]->handle(), 0);
    }

    // Depth-Stencil attachments.
    depth_stencil_attachment_ = std::make_shared<texture_2d>("depth_stencil", _width, _height, sized_format::depth24_stencil8);
    glNamedFramebufferTexture(handle_, GL_DEPTH_STENCIL_ATTACHMENT, depth_stencil_attachment_->handle(), 0);
}

GLSL代码:

uniform sampler2D u_texture_gbuffer_position;
uniform sampler2D u_texture_gbuffer_normal;
uniform sampler2D u_texture_gbuffer_albedo;
uniform sampler2D u_texture_gbuffer_specular;
uniform sampler2D u_texture_gbuffer_gloss;

const vec3 position = texture(u_texture_gbuffer_position, io_tex_coord.xy).rgb; // All zeros.
const vec3 normal = texture(u_texture_gbuffer_normal, io_tex_coord.xy).rgb; // All zeroes.
const vec4 albedo = texture(u_texture_gbuffer_albedo, io_tex_coord.xy); // Has correct values.
const vec4 specular = texture(u_texture_gbuffer_specular, io_tex_coord.xy); // Has correct values.
const float gloss = texture(u_texture_gbuffer_gloss, io_tex_coord.xy).r; // All zeroes.

【问题讨论】:

  • 具有 RGB 格式的纹理不一定是可渲染的。参见Texture and Renderbuffer
  • GL_RED 的光泽纹理怎么样?它是一个 32 位浮点红色,根据规范应该是可渲染的。

标签: c++ opengl


【解决方案1】:

我解决了这个问题。启用了 GL_BLEND,这意味着任何 alpha 值为 0 的片段基本上都被丢弃了。

因此,即使我正在写入只有 1 或 3 个组件的纹理,因为默认情况下它们的 alpha 值为 0.0f,甚至它们的 RGB 值也因某种原因被丢弃。

所以解决方案是在我的几何过程中禁用 GL_BLEND 以确保所有纹理都被正确写入而不会丢弃它们的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多