I'm implementing motion blur, in particular this one: http://mynameismjp.w...on-blur-sample/
All went well, however I noticed a tiny problem: MJP doesn't encode the velocity information. I thought no problem, let's do a scale-bias, so that the coordinates get transformed from [-1, 1] to [0, 1], and then I can store them in an RGBA texture's xy channels.
Then came the surprise, when I do motion blur, the whole scene became blurred a bit, and when I moved around I saw screen tearing everywhere. The first symptom's cause is obvious, for some reason the precision isn't that good, and therefore 0 * 0.5 + 0.5 = x became x > 0.5.
Where x is the encoded velocity. Now where x should be 0 (no movement) it was around 0.005.
So I added a threshold, if x < 0.006 then no blur. Hooray this solved the blurring problem, but not the tearing.
So I started to investigate this further, as the technique seemed to be very easy to implement I suppose I did it correctly. Now When I masked the screen ( white where blur, black where no blur) I noticed that as I move around certain areas fall below the threshold and therefore they don't get blurred. This symptom is most noticable when I move horizontally. After a certain point the screen is no longer blurred. See on video:
and here's the source code:
c++ g-buffer rendering code:
[c++ code, rendering] o->mvm.push_matrix(); mm::vec4 diff_color( 0.9f, 0.9f, 0.9f, 1.0f ); coloring_shader->bind(); coloring_shader->pass_m4x4( o->ppl.get_model_view_matrix(), "modelview" ); coloring_shader->pass_m4x4( o->ppl.get_projection_matrix(), "proj" ); coloring_shader->pass_m3x3( o->ppl.get_normal_matrix( false ), "normal_mat" ); coloring_shader->pass_vec4( diff_color, "diff_color" ); coloring_shader->pass_float( -1.0f / event::get()->get_resize()->get_data()->far, "inv_neg_far" ); //in the first frame I upload a identity matrix as the previous, in the next frame it is fixed. coloring_shader->pass_m4x4( o->ppl.get_projection_matrix() * coloring_prev, "previous_mat" ); coloring_prev = o->mvm.get_matrix(); render_mesh( test_mesh ); coloring_shader->unbind(); o->mvm.pop_matrix();
G-buffer rendering (including velocity buffer)
[vertex shader]
#version 410
uniform mat4 modelview, proj;
uniform mat3 normal_mat;
uniform mat4 previous_mat;
in vec3 in_normal;
in vec4 in_vertex;
out cross_shader_data
{
vec3 vs_normal;
vec4 vs_position;
vec4 prev_vector;
vec4 curr_vector;
} o;
void main()
{
o.vs_normal = normalize(normal_mat * in_normal);
o.vs_position = modelview * in_vertex;
o.prev_vector = previous_mat * in_vertex;
o.curr_vector = proj * o.vs_position;
gl_Position = o.curr_vector;
}
[pixel shader]
#version 410
uniform vec4 diff_color;
uniform float inv_neg_far;
in cross_shader_data
{
vec3 vs_normal;
vec4 vs_position;
vec4 prev_vector;
vec4 curr_vector;
} i;
out vec4 albedo;
out vec4 normal;
out vec4 depth;
out vec4 extra;
void main()
{
albedo = diff_color;
normal = vec4(i.vs_normal * 0.5 + 0.5, 1.0);
depth.x = i.vs_position.z * inv_neg_far;
//transform clip space to ndc, then scale / bias to store it
extra = vec4((i.curr_vector.xy / i.curr_vector.w - i.prev_vector.xy / i.prev_vector.w) * 0.5 + 0.5, 0, 0);
}
blurring pass:
#version 410
uniform sampler2D texture0; //shading result
uniform sampler2D texture1; //velocity buffer
in cross_shader_data
{
vec2 tex_coord;
} i;
out vec4 color;
void main()
{
vec2 velocity_vec = texture(texture1, i.tex_coord).xy * 2.0 - 1.0; //scale and bias back
if(length(velocity_vec) < 0.006)
{
color = texture(texture0, i.tex_coord);
return;
}
vec4 result = vec4(0.0);
int num_of_samples = 16;
//clamp the velocity to make sure that there's no undersampling
vec2 max_velocity = (2.0 * float(num_of_samples)) / textureSize(texture0, 0);
velocity_vec = clamp(velocity_vec, -max_velocity, max_velocity);
for(int c = 0; c < num_of_samples; c++)
{
vec2 sample_coord = i.tex_coord + (float(velocity_vec) * (c / float(num_of_samples)));
//sample & add to result:
result += texture(texture0, sample_coord);
}
color = result / float(num_of_samples);
}
any ideas what am I doing wrong / how to solve this?
Edited by Yours3!f, 24 July 2012 - 05:45 AM.






