From 90915524c108d796195a10bedda40367d81f9f97 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Fri, 20 Jul 2018 11:19:28 +0200 Subject: [PATCH] Finish up the variational refinement, conceptually. Of course, it doesn't work yet. --- add_base_flow.frag | 11 ++++++++ flow.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++-- motion_search.frag | 12 ++------- 3 files changed, 76 insertions(+), 12 deletions(-) create mode 100644 add_base_flow.frag diff --git a/add_base_flow.frag b/add_base_flow.frag new file mode 100644 index 0000000..2e774da --- /dev/null +++ b/add_base_flow.frag @@ -0,0 +1,11 @@ +#version 450 core + +in vec2 tc; +out vec2 diff_flow; + +uniform sampler2D diff_flow_tex; + +void main() +{ + diff_flow = texture(diff_flow_tex, tc).xy; +} diff --git a/flow.cpp b/flow.cpp index 177a140..5e93cd8 100644 --- a/flow.cpp +++ b/flow.cpp @@ -709,6 +709,8 @@ SOR::SOR() uniform_diff_flow_tex = glGetUniformLocation(sor_program, "diff_flow_tex"); uniform_equation_tex = glGetUniformLocation(sor_program, "equation_tex"); + uniform_smoothness_x_tex = glGetUniformLocation(sor_program, "smoothness_x_tex"); + uniform_smoothness_y_tex = glGetUniformLocation(sor_program, "smoothness_y_tex"); } void SOR::exec(GLuint diff_flow_tex, GLuint equation_tex, GLuint smoothness_x_tex, GLuint smoothness_y_tex, int level_width, int level_height, int num_iterations) @@ -737,6 +739,59 @@ void SOR::exec(GLuint diff_flow_tex, GLuint equation_tex, GLuint smoothness_x_te } } +// Simply add the differential flow found by the variational refinement to the base flow. +// The output is in diff_flow_tex; we don't need to make a new texture. +class AddBaseFlow { +public: + AddBaseFlow(); + void exec(GLuint base_flow_tex, GLuint diff_flow_tex, int level_width, int level_height); + +private: + GLuint add_flow_vs_obj; + GLuint add_flow_fs_obj; + GLuint add_flow_program; + GLuint add_flow_vao; + + GLuint uniform_base_flow_tex; +}; + +AddBaseFlow::AddBaseFlow() +{ + add_flow_vs_obj = compile_shader(read_file("vs.vert"), GL_VERTEX_SHADER); + add_flow_fs_obj = compile_shader(read_file("add_base_flow.frag"), GL_FRAGMENT_SHADER); + add_flow_program = link_program(add_flow_vs_obj, add_flow_fs_obj); + + // Set up the VAO containing all the required position/texcoord data. + glCreateVertexArrays(1, &add_flow_vao); + glBindVertexArray(add_flow_vao); + glBindBuffer(GL_ARRAY_BUFFER, vertex_vbo); + + GLint position_attrib = glGetAttribLocation(add_flow_program, "position"); + glEnableVertexArrayAttrib(add_flow_vao, position_attrib); + glVertexAttribPointer(position_attrib, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); + + uniform_base_flow_tex = glGetUniformLocation(add_flow_program, "base_flow_tex"); +} + +void AddBaseFlow::exec(GLuint base_flow_tex, GLuint diff_flow_tex, int level_width, int level_height) +{ + glUseProgram(add_flow_program); + + bind_sampler(add_flow_program, uniform_base_flow_tex, 0, base_flow_tex, nearest_sampler); + + GLuint add_flow_fbo; // TODO: cleanup + glCreateFramebuffers(1, &add_flow_fbo); + glNamedFramebufferTexture(add_flow_fbo, GL_COLOR_ATTACHMENT0, diff_flow_tex, 0); + + glViewport(0, 0, level_width, level_height); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + glBindVertexArray(add_flow_vao); + glBindFramebuffer(GL_FRAMEBUFFER, add_flow_fbo); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); +} + int main(void) { if (SDL_Init(SDL_INIT_EVERYTHING) == -1) { @@ -800,7 +855,7 @@ int main(void) // Initial flow is zero, 1x1. GLuint initial_flow_tex; glCreateTextures(GL_TEXTURE_2D, 1, &initial_flow_tex); - glTextureStorage2D(initial_flow_tex, 1, GL_RGB32F, 1, 1); + glTextureStorage2D(initial_flow_tex, 1, GL_RG16F, 1, 1); GLuint prev_level_flow_tex = initial_flow_tex; @@ -812,6 +867,7 @@ int main(void) ComputeSmoothness compute_smoothness; SetupEquations setup_equations; SOR sor; + AddBaseFlow add_base_flow; GLuint query; glGenQueries(1, &query); @@ -919,7 +975,12 @@ int main(void) sor.exec(du_dv_tex, equation_tex, smoothness_x_tex, smoothness_y_tex, level_width, level_height, 5); } - prev_level_flow_tex = dense_flow_tex; + // Add the differential flow found by the variational refinement to the base flow, + // giving the final flow estimate for this level. + // The output is in diff_flow_tex; we don't need to make a new texture. + add_base_flow.exec(dense_flow_tex, du_dv_tex, level_width, level_height); + + prev_level_flow_tex = du_dv_tex; } glEndQuery(GL_TIME_ELAPSED); diff --git a/motion_search.frag b/motion_search.frag index 7690389..188f5c3 100644 --- a/motion_search.frag +++ b/motion_search.frag @@ -90,16 +90,8 @@ void main() mat2 H_inv = inverse(H); - // Fetch the initial guess for the flow. (We need the normalization step - // because densification works by accumulating; see the comments on the - // Densify class.) - vec3 prev_flow = texture(flow_tex, flow_tc).xyz; - vec2 initial_u; - if (prev_flow.z < 1e-3) { - initial_u = vec2(0.0, 0.0); - } else { - initial_u = prev_flow.xy / prev_flow.z; - } + // Fetch the initial guess for the flow. + vec2 initial_u = texture(flow_tex, flow_tc).xy; // Note: The flow is in OpenGL coordinates [0..1], but the calculations // generally come out in pixels since the gradient is in pixels, -- 2.39.2