我在使用OpenGL实现多过程着色器以启用HDR时遇到了一个问题。
第二步使用具有颜色和深度的帧缓冲区渲染为四边形。
this tutorial
.)
问题是它不会渲染某些(正面、顶部和一侧)立方体面。
这是渲染器初始化时使用的代码:
Renderer::Renderer(Window window): window(window) {
this->materials = std::map<std::string, Material>();
this->meshes = std::map<std::string, Mesh>();
// glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glEnable(GL_FRAMEBUFFER_SRGB);
glViewport(0, 0, window.width, window.height);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
this->load_textures();
this->load_materials();
this->load_meshes();
this->load_shader_programs();
this->create_hdr(this->shader_programs.find("hdr")->second);
}
这将在第一次渲染之前生成帧缓冲区:
void Renderer::create_hdr(ShaderProgram sp_hdr) {
glGenFramebuffers(1, &this->hdr_fbo);
glGenTextures(1, &this->color_buffer);
glBindTexture(GL_TEXTURE_2D, this->color_buffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, this->window.width, this->window.height, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenRenderbuffers(1, &this->render_buffer);
glBindRenderbuffer(GL_RENDERBUFFER, this->render_buffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, this->window.width, this->window.height);
glBindFramebuffer(GL_FRAMEBUFFER, this->hdr_fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->color_buffer, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, this->depth_buffer);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
std::cout << "Framebuffer not complete!" << std::endl;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glUseProgram(sp_hdr.id);
glUniform1i(glGetUniformLocation(sp_hdr.id, "hdr_buffer"), 0);
}
这将在两个过程中渲染级别:
void Renderer::render(Level level, Camera camera, std::vector<std::reference_wrapper<DirectionalLight>> d_lights, std::vector<PointLight> p_lights, std::vector<SpotLight> s_lights) {
// 1. First Pass - HDR
glBindFramebuffer(GL_FRAMEBUFFER, this->hdr_fbo);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ShaderProgram sp_render = this->shader_programs.find("render")->second;
glUseProgram(sp_render.id);
attach_camera(camera, sp_render);
attach_projection_matrix(camera, sp_render);
attach_view_matrix(camera, sp_render);
unsigned int d_light_num = 0;
for (DirectionalLight d_light : d_lights) {
attach_d_light(d_light, sp_render, d_light_num);
d_light_num++;
}
for (Block block : level.blocks) {
attach_position(block.position, sp_render);
Material material = this->materials.find(block.material_id)->second;
attach_material(material, sp_render);
Mesh mesh = this->meshes.find(block.mesh_id)->second;
draw_mesh(mesh, sp_render);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// 2. Second Pass - Render to quad
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ShaderProgram sp_hdr = this->shader_programs.find("hdr")->second;
glUseProgram(sp_hdr.id);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, this->color_buffer);
draw_mesh(this->meshes.find("quad")->second, sp_hdr);
}