X-Git-Url: https://git.sesse.net/?p=movit;a=blobdiff_plain;f=blur_effect.cpp;h=17044f12f35c54681148814f38efebac4d37f5e0;hp=ddf542eec62fea98c362ba726d3b942bb0b61fa7;hb=0c1fab7813e12580bed0852d9e57b0a3f2768d83;hpb=c0461658ca2abaa10aae42f40ffee7e5128bc7ab diff --git a/blur_effect.cpp b/blur_effect.cpp index ddf542e..17044f1 100644 --- a/blur_effect.cpp +++ b/blur_effect.cpp @@ -3,14 +3,17 @@ #include #include #include +#include #include "blur_effect.h" #include "util.h" BlurEffect::BlurEffect() - : radius(3.0f) + : radius(3.0f), + direction(HORIZONTAL) { register_float("radius", (float *)&radius); + register_int("direction", (int *)&direction); } std::string BlurEffect::output_fragment_shader() @@ -22,22 +25,53 @@ void BlurEffect::set_uniforms(GLuint glsl_program_num, const std::string &prefix { Effect::set_uniforms(glsl_program_num, prefix, sampler_num); - //glActiveTexture(GL_TEXTURE0); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3); - //check_error(); + // We only have 15 taps to work with, and we want that to reach out to about 2.5*sigma. + // Bump up the mipmap levels (giving us box blurs) until we have what we need. + unsigned base_mipmap_level = 0; + float adjusted_radius = radius; + float pixel_size = 1.0f; + while (adjusted_radius * 2.5f > 7.0f) { + ++base_mipmap_level; + adjusted_radius *= 0.5f; + pixel_size *= 2.0f; + } - set_uniform_float(glsl_program_num, prefix, "pixel_offset", 1.0f / 1280.0f); // FIXME + // In the second pass, we do the same, but don't sample from a mipmap; + // that would re-blur the other direction in an ugly fashion, and we already + // have the vertical box blur we need from that pass. + // + // TODO: We really need to present horizontal+vertical as a unit; + // currently, there's really no guarantee vertical blur is the second pass. + if (direction == VERTICAL) { + base_mipmap_level = 0; + } + + glActiveTexture(GL_TEXTURE0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, base_mipmap_level); + check_error(); + + // FIXME + if (direction == HORIZONTAL) { + float ps[] = { pixel_size / 1280.0f, 0.0f }; + set_uniform_vec2(glsl_program_num, prefix, "pixel_offset", ps); + } else if (direction == VERTICAL) { + float ps[] = { 0.0f, pixel_size / 720.0f }; + set_uniform_vec2(glsl_program_num, prefix, "pixel_offset", ps); + } else { + assert(false); + } // Simple Gaussian weights for now. float weight[15], total = 0.0f; for (unsigned i = 0; i < 15; ++i) { - float z = (i - 7.0f) / radius; + float z = (i - 7.0f) / adjusted_radius; weight[i] = exp(-(z*z)); total += weight[i]; } + printf("[mip level %d] ", base_mipmap_level); for (unsigned i = 0; i < 15; ++i) { weight[i] /= total; - printf("%f\n", weight[i]); + printf("%f ", weight[i]); } printf("\n"); set_uniform_float_array(glsl_program_num, prefix, "weight", weight, 15);