GLSL Motion Blur Post 处理,进入着色器的 2 个纹理相同
GLSL Motion Blur Post Processing, 2 textures going to the shader are the same
我正在使用 OpenGL 创建场景、渲染它并对其应用运动模糊 post 过程。
我有一个用于初始渲染场景的临时帧和 post 处理中使用的另外 2 个帧 - 当前帧和前一帧。
每次调用render方法时,当前帧和上一帧翻转,即第0帧:当前= 0,上一帧= 1。第2帧:当前= 1,上一帧= 0。
渲染方法如下:
首先我将渲染目标设置为临时帧
glBindFrameBuffer
。
然后我清除框架并将场景渲染到它。
接下来我将渲染目标设置为当前帧,清除它并将运动模糊效果与 glUseProgram
绑定。然后,我将一个 4x4 单位矩阵发送到着色器,作为渲染到屏幕的四边形的模型-视图-投影矩阵的制服(就像所有 post 处理方法一样)。
然后 - 现在这是我认为出错的地方 - 我使用 glActiveTexture(GL_TEXTURE0 + index)
和 glBindTexture
(来自 glew)绑定 2 个纹理。这些是临时帧纹理和前一帧纹理。
之后,我将一个混合因子发送到着色器,用于我刚刚发送的 2 个纹理之间的混合操作。然后我渲染到屏幕四边形。
最后,我将渲染目标设置为屏幕,绑定(最终)纹理效果,发送单位矩阵,将当前帧纹理绑定到它并再次渲染到屏幕四边形。
场景确实渲染但没有运动模糊。
难道上一帧什么都没有?我认为可能是这种情况,所以我通过从另一个纹理中减去一个纹理在运动模糊着色器中对其进行了测试。结果是黑屏(两种方式我都测试过)。所以这意味着 2 个纹理是相同的,对吗?我四处移动了相机,所以如果没有,它至少应该闪烁。我什至通过向更新方法添加 Sleep
来降低 fps,结果相同。
感谢任何帮助,谢谢。
main中的代码:
bool render()
{
// !!!!!!!!!!!!!!! FIRST PASS !!!!!!!!!!!!!!!!
unsigned int previous_frame = ((current_frame) == 1) ? 0 : 1;
// *******************************
// Set render target to temp frame
// *******************************
renderer::set_render_target(temp_frame);
// ***********
// Clear frame
// ***********
renderer::clear();
// Render meshes
for (auto &e : meshes)
{
auto m = e.second;
// Bind effect
renderer::bind(eff);
// Create MVP matrix
auto M = m.get_transform().get_transform_matrix();
auto V = cam.get_view();
auto P = cam.get_projection();
auto MVP = P * V * M;
// Set MVP matrix uniform
glUniformMatrix4fv(
eff.get_uniform_location("MVP"), // Location of uniform
1, // Number of values - 1 mat4
GL_FALSE, // Transpose the matrix?
value_ptr(MVP)); // Pointer to matrix data
// Create MV matrix
auto MV = V * M;
// Set MV matrix uniform
glUniformMatrix4fv(
eff.get_uniform_location("MV"), // Location of uniform
1, // Number of values - 1 mat4
GL_FALSE, // Transpose the matrix?
value_ptr(MV)); // Pointer to matrix data
// Set M matrix uniform
glUniformMatrix4fv(
eff.get_uniform_location("M"),
1,
GL_FALSE,
value_ptr(M));
// Set N matrix uniform
glUniformMatrix3fv(
eff.get_uniform_location("N"),
1,
GL_FALSE,
value_ptr(m.get_transform().get_normal_matrix()));
// Bind material
renderer::bind(m.get_material(), "mat");
// Bind light
renderer::bind(light, "light");
// Bind texture
renderer::bind(tex, 0);
// Set tex uniform
glUniform1i(eff.get_uniform_location("tex"), 0);
// Set eye position
glUniform3fv(eff.get_uniform_location("eye_pos"), 1, value_ptr(cam.get_position()));
// Render mesh
renderer::render(m);
}
// !!!!!!!!!!!!!!! SECOND PASS !!!!!!!!!!!!!!!!
// **********************************
// Set render target to current frame
// **********************************
renderer::set_render_target(frames[current_frame]);
// ***********
// Clear frame
// ***********
renderer::clear();
// ***********************
// Bind motion blur effect
// ***********************
renderer::bind(motion_blur);
// ******************************
// MVP is now the identity matrix
// ******************************
auto MVP = ident;
glUniformMatrix4fv(motion_blur.get_uniform_location("MVP"), 1, GL_FALSE, value_ptr(MVP));
// ***********
// Bind frames
// ***********
renderer::bind(temp_frame.get_frame(), 0);
renderer::bind(frames[previous_frame].get_frame(), 1);
// ****************
// Set blend factor
// ****************
float blend_factor = 0.5;
glUniform1f(motion_blur.get_uniform_location("blend_factor"), blend_factor);
// ******************
// Render screen quad
// ******************
renderer::render(screen_quad);
// !!!!!!!!!!!!!!! SCREEN PASS !!!!!!!!!!!!!!!!
// ************************************
// Set render target back to the screen
// ************************************
renderer::set_render_target();
// Use texturing effect
renderer::bind(tex_eff);
// **********************
// Set MVP matrix uniform (Model View Projection, now identity)
// **********************
glUniformMatrix4fv(tex_eff.get_uniform_location("MVP"), 1, GL_FALSE, value_ptr(MVP));
// ******************************
// Bind texture from frame buffer
// ******************************
renderer::bind(frames[current_frame].get_frame(), 0);
// **********************
// Render the screen quad
// **********************
renderer::render(screen_quad);
return true;
}
我的运动模糊着色器中的代码:
#version 410
// Current frame being rendered
uniform sampler2D tex;
// Previous frame
uniform sampler2D previous_frame;
// Blend factor between frames
uniform float blend_factor;
// Incoming texture coordinate
layout (location = 0) in vec2 tex_coord;
// Outgoing colour
layout (location = 0) out vec4 colour;
void main()
{
vec4 out_colour;
// ***********************
// Sample the two textures
// ***********************
vec4 current = texture(tex, tex_coord);
vec4 previous = texture(previous_frame, tex_coord);
// *****************************
// Mix between these two colours
// *****************************
out_colour = mix(current, previous, blend_factor);
// *******************
// Ensure alpha is 1.0
// *******************
out_colour.w = 1.0;
colour = out_colour;
}
我忘记在绑定它们之前用 glUniform1i() 设置 2 个纹理的制服。
我正在使用 OpenGL 创建场景、渲染它并对其应用运动模糊 post 过程。
我有一个用于初始渲染场景的临时帧和 post 处理中使用的另外 2 个帧 - 当前帧和前一帧。
每次调用render方法时,当前帧和上一帧翻转,即第0帧:当前= 0,上一帧= 1。第2帧:当前= 1,上一帧= 0。
渲染方法如下:
首先我将渲染目标设置为临时帧
glBindFrameBuffer
。
然后我清除框架并将场景渲染到它。
接下来我将渲染目标设置为当前帧,清除它并将运动模糊效果与 glUseProgram
绑定。然后,我将一个 4x4 单位矩阵发送到着色器,作为渲染到屏幕的四边形的模型-视图-投影矩阵的制服(就像所有 post 处理方法一样)。
然后 - 现在这是我认为出错的地方 - 我使用 glActiveTexture(GL_TEXTURE0 + index)
和 glBindTexture
(来自 glew)绑定 2 个纹理。这些是临时帧纹理和前一帧纹理。
之后,我将一个混合因子发送到着色器,用于我刚刚发送的 2 个纹理之间的混合操作。然后我渲染到屏幕四边形。
最后,我将渲染目标设置为屏幕,绑定(最终)纹理效果,发送单位矩阵,将当前帧纹理绑定到它并再次渲染到屏幕四边形。
场景确实渲染但没有运动模糊。
难道上一帧什么都没有?我认为可能是这种情况,所以我通过从另一个纹理中减去一个纹理在运动模糊着色器中对其进行了测试。结果是黑屏(两种方式我都测试过)。所以这意味着 2 个纹理是相同的,对吗?我四处移动了相机,所以如果没有,它至少应该闪烁。我什至通过向更新方法添加 Sleep
来降低 fps,结果相同。
感谢任何帮助,谢谢。
main中的代码:
bool render()
{
// !!!!!!!!!!!!!!! FIRST PASS !!!!!!!!!!!!!!!!
unsigned int previous_frame = ((current_frame) == 1) ? 0 : 1;
// *******************************
// Set render target to temp frame
// *******************************
renderer::set_render_target(temp_frame);
// ***********
// Clear frame
// ***********
renderer::clear();
// Render meshes
for (auto &e : meshes)
{
auto m = e.second;
// Bind effect
renderer::bind(eff);
// Create MVP matrix
auto M = m.get_transform().get_transform_matrix();
auto V = cam.get_view();
auto P = cam.get_projection();
auto MVP = P * V * M;
// Set MVP matrix uniform
glUniformMatrix4fv(
eff.get_uniform_location("MVP"), // Location of uniform
1, // Number of values - 1 mat4
GL_FALSE, // Transpose the matrix?
value_ptr(MVP)); // Pointer to matrix data
// Create MV matrix
auto MV = V * M;
// Set MV matrix uniform
glUniformMatrix4fv(
eff.get_uniform_location("MV"), // Location of uniform
1, // Number of values - 1 mat4
GL_FALSE, // Transpose the matrix?
value_ptr(MV)); // Pointer to matrix data
// Set M matrix uniform
glUniformMatrix4fv(
eff.get_uniform_location("M"),
1,
GL_FALSE,
value_ptr(M));
// Set N matrix uniform
glUniformMatrix3fv(
eff.get_uniform_location("N"),
1,
GL_FALSE,
value_ptr(m.get_transform().get_normal_matrix()));
// Bind material
renderer::bind(m.get_material(), "mat");
// Bind light
renderer::bind(light, "light");
// Bind texture
renderer::bind(tex, 0);
// Set tex uniform
glUniform1i(eff.get_uniform_location("tex"), 0);
// Set eye position
glUniform3fv(eff.get_uniform_location("eye_pos"), 1, value_ptr(cam.get_position()));
// Render mesh
renderer::render(m);
}
// !!!!!!!!!!!!!!! SECOND PASS !!!!!!!!!!!!!!!!
// **********************************
// Set render target to current frame
// **********************************
renderer::set_render_target(frames[current_frame]);
// ***********
// Clear frame
// ***********
renderer::clear();
// ***********************
// Bind motion blur effect
// ***********************
renderer::bind(motion_blur);
// ******************************
// MVP is now the identity matrix
// ******************************
auto MVP = ident;
glUniformMatrix4fv(motion_blur.get_uniform_location("MVP"), 1, GL_FALSE, value_ptr(MVP));
// ***********
// Bind frames
// ***********
renderer::bind(temp_frame.get_frame(), 0);
renderer::bind(frames[previous_frame].get_frame(), 1);
// ****************
// Set blend factor
// ****************
float blend_factor = 0.5;
glUniform1f(motion_blur.get_uniform_location("blend_factor"), blend_factor);
// ******************
// Render screen quad
// ******************
renderer::render(screen_quad);
// !!!!!!!!!!!!!!! SCREEN PASS !!!!!!!!!!!!!!!!
// ************************************
// Set render target back to the screen
// ************************************
renderer::set_render_target();
// Use texturing effect
renderer::bind(tex_eff);
// **********************
// Set MVP matrix uniform (Model View Projection, now identity)
// **********************
glUniformMatrix4fv(tex_eff.get_uniform_location("MVP"), 1, GL_FALSE, value_ptr(MVP));
// ******************************
// Bind texture from frame buffer
// ******************************
renderer::bind(frames[current_frame].get_frame(), 0);
// **********************
// Render the screen quad
// **********************
renderer::render(screen_quad);
return true;
}
我的运动模糊着色器中的代码:
#version 410
// Current frame being rendered
uniform sampler2D tex;
// Previous frame
uniform sampler2D previous_frame;
// Blend factor between frames
uniform float blend_factor;
// Incoming texture coordinate
layout (location = 0) in vec2 tex_coord;
// Outgoing colour
layout (location = 0) out vec4 colour;
void main()
{
vec4 out_colour;
// ***********************
// Sample the two textures
// ***********************
vec4 current = texture(tex, tex_coord);
vec4 previous = texture(previous_frame, tex_coord);
// *****************************
// Mix between these two colours
// *****************************
out_colour = mix(current, previous, blend_factor);
// *******************
// Ensure alpha is 1.0
// *******************
out_colour.w = 1.0;
colour = out_colour;
}
我忘记在绑定它们之前用 glUniform1i() 设置 2 个纹理的制服。