GLSL Motion Blur Post Processing,进入着色器的 2 个纹理是相同的
Posted
技术标签:
【中文标题】GLSL Motion Blur Post Processing,进入着色器的 2 个纹理是相同的【英文标题】:GLSL Motion Blur Post Processing, 2 textures going to the shader are the same 【发布时间】:2016-06-20 00:37:23 【问题描述】:我正在使用 OpenGL 创建一个场景,对其进行渲染并对其应用运动模糊后期处理。
我有一个临时帧用于初始渲染场景,还有 2 个用于后期处理的其他帧 - 当前帧和前一帧。
每次调用render方法时,当前帧和上一帧都会翻转,即第0帧:current=0,previous=1。第2帧:current=1,previous=0。
渲染方法如下:
首先我将渲染目标设置为临时框架
glBindFrameBuffer
。
然后我清除框架并将场景渲染到它。
接下来我将渲染目标设置为当前帧,清除它并将运动模糊效果与glUseProgram
绑定。然后我将一个 4x4 单位矩阵发送到着色器,作为渲染到屏幕上的四边形的模型-视图-投影矩阵的统一(就像所有后处理方法一样)。
然后 - 现在这是我认为出错的地方 - 我使用 glActiveTexture(GL_TEXTURE0 + index)
和 glBindTexture
(来自 glew)绑定了 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;
【问题讨论】:
【参考方案1】:我忘记在绑定之前用 glUniform1i() 设置这两个纹理的制服。
【讨论】:
以上是关于GLSL Motion Blur Post Processing,进入着色器的 2 个纹理是相同的的主要内容,如果未能解决你的问题,请参考以下文章
By virtue of|sustain|post |scrape off |stretch|access to|take into account of|exploit|hasten|blur |i
iOS 14中出现屏幕刷新率选项:iPhone 12 Pro上120Hz稳了?
WordPress:函数声明 WC_Gateway_PayPal_Pro_PayFlow::get_post_data($order) 应该与 WC_Settings_API::get_post_da