Ich benutze OpenGL, um eine Szene zu erstellen, sie zu rendern und einen Bewegungsunschärfe-Nachbearbeitungsprozess darauf anzuwenden.GLSL Motion Blur Nachbearbeitung, 2 Texturen, die zum Shader gehen, sind gleich
Ich habe einen temporären Frame, um die Szene zu rendern und 2 andere Frames, die in der Nachbearbeitung verwendet werden - Ein aktueller Frame und ein vorheriger Frame.
Der aktuelle Frame und vorherige Rahmens werden jedesmal, wenn die Render-Methode umgedreht wird, das heißt Frame-0 genannt: current = 0, = 1. vorheriger Frame 2: current = 1, vorhergehende = 0.
Die Render Methode ist wie folgt:
Zuerst setze ich mein Renderziel auf den Temp-Frame mit glBindFrameBuffer
. Dann lösche ich den Rahmen und render die Szene dazu.
Als nächstes setze ich das Renderziel auf das aktuelle Bild, lösche das und verbinde den Bewegungsunschärfe-Effekt mit glUseProgram
. Dann sende ich eine 4x4-Identitätsmatrix an den Shader als eine Uniform für die Modellansicht-Projektionsmatrix des Quads, die auf den Bildschirm gerendert wird (genau wie bei allen Post-Processing-Methoden).
Dann - jetzt ist das das Bit, das ich glaube schief geht - ich bindung 2 Texturen mit glActiveTexture(GL_TEXTURE0 + index)
und glBindTexture
(von glew). Dies sind die temporäre Rahmenstruktur und die vorherige Rahmenstruktur.
Anschließend sende ich einen Mischfaktor an den Shader, der in einem Mischvorgang zwischen den beiden Texturen verwendet wird, die ich gerade gesendet habe. Dann rendere ich zum Bildschirmviereck.
Schließlich setze ich das Renderziel auf den Bildschirm, binde den (ultimativen) Textureffekt, sende die Identitätsmatrix, binde die aktuelle Rahmentextur daran und rende es noch einmal auf den Bildschirmviereck.
Die Szene rendert aber ohne Bewegungsunschärfe.
Könnte es sein, dass nichts in den vorherigen Frame geht? Ich dachte, dass dies der Fall sein könnte, also teste ich es im Bewegungsunschärfe-Shader, indem ich eine Textur von der anderen subtrahiere. Das Ergebnis war ein schwarzer Bildschirm (ich testete beides). Das bedeutet also, dass die 2 Texturen gleich sind, oder? Ich bewegte die Kamera herum, so dass es zumindest flackern sollte, wenn sie es nicht waren. Ich habe sogar die fps reduziert, indem ich ein Sleep
Update-Methode hinzugefügt habe, das gleiche Ergebnis.
Jede Hilfe wird geschätzt, danke.
Der Code in 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;
}
Der Code in meinem Motion Blur-Shader:
#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;
}