2016-06-20 23 views
0

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; 
} 

Antwort

1

ich die Uniformen der 2 Texturen mit glUniform1i (gesetzt hatte vergessen), bevor sie verbindlich.