1

I'm currently trying to create some motion blur effects in glsl for a game I'm working on. To do so, I've found a very interesting article explaining a screen space technique here => http://john-chapman-graphics.blogspot.com/2013/01/what-is-motion-blur-motion-pictures-are.html

I ended up with the code below:

#version 330 core

in GS_OUT
{
    vec2 tCoords;
} fs_in;

uniform float fps;
uniform sampler2D depthTexture;
uniform sampler2D colorTexture;

uniform float width;
uniform float height;

uniform mat4 inv_MVP;
uniform mat4 prev_MVP;

uniform int smoke;
uniform int env;

uniform float pod_speed;

out vec4 color;

float linearizeDepth(float depth)
{
    float z = (depth * 2.0) - 1.0;
    return (2.0 * 1000.0) / (1001.0 - z * 999.0);
}

void main()
{
    float depth = linearizeDepth(texture(depthTexture, fs_in.tCoords).r);
    depth = depth / 1000.0;

    // compute view ray
    float xOffset = (width / 2.0);
    xOffset *= (fs_in.tCoords.x * 2.0 - 1.0);
    float yOffset = (height / 2.0);
    yOffset *= ((1.0 - fs_in.tCoords.y) * 2.0 - 1.0);

    vec3 horizontal_offset = vec3(1.0, 0.0, 0.0) * xOffset;
    vec3 vertical_offset = vec3(0.0, 1.0, 0.0) * yOffset;

    vec3 view_ray = vec3(0.0, 0.0, 1000.1) + horizontal_offset + vertical_offset;

    // compute world pos
    vec3 current = view_ray * depth;
    current = vec3(inv_MVP * vec4(current, 1.0));

    // compute previous screen space position
    vec4 previous = prev_MVP * vec4(current, 1.0);
    previous.xyz /= previous.w;
    previous.xy = previous.xy * 0.5 + 0.5;

    // compute blur vector
    vec2 blur_vector = previous.xy - fs_in.tCoords;

    // process blur
    float blurScale = fps / 60.0;
    if(env == 1)
        blur_vector *= 0.25 * (pod_speed / 300.0);
    else if(smoke == 1)
        blur_vector *= 0.1;

    color = texture(colorTexture, fs_in.tCoords);
    int samples = 15;
    for(int i = 1; i < samples; i++)
    {
        vec2 offset;
        if(env == 1)
            offset = blur_vector * (float(i) / float(samples - 1) - 0.5);
        else if(smoke == 1)
            offset = blur_vector * (float(i) / float(samples - 1));
        color += texture(colorTexture, fs_in.tCoords + offset);
    }
    color /= samples;
}

Now, the problem is that the blur vector remains the same in world coordinates. It is properly set for the initial position of the vehicle (straight forward), but when I turn left, the blur vector consequently heads towards the right (same stuff happening when I turn right, blur vector is pointing left).

What could possibly cause that behavior ?

I also tried to compute the view ray like this

// compute view ray
    float xOffset = (fs_in.tCoords.x * 2.0 - 1.0);
    float yOffset = ((1.0 - fs_in.tCoords.y) * 2.0 - 1.0);

    vec3 horizontal_offset = vec3(1.0, 0.0, 0.0) * xOffset;
    vec3 vertical_offset = vec3(0.0, 1.0, 0.0) * yOffset;

    vec3 view_ray = vec3(0.0, 0.0, 1.0) + horizontal_offset + vertical_offset;

But I get the same effect.

=-=-=-=-=-=-=-=-=-= SCREENSHOTS =-=-=-=-=-=-=-=-=-=

correct motion blur (just moving straight forward since the beginning of the game)

motion blur once I turned to the left

and once I turned to the right

note: the model matrix inside the MVP matrix is set to identity

  • did you try to invert the sign of `xOffset`? – Yakov Galka Jan 02 '20 at 06:20
  • I've just tried, and unfortunately that doesn't change anything, thank you though ! –  Jan 02 '20 at 12:16
  • Inverting the `xOffset` shall invert the effect horizontally. If it doesn't, try figuring out why. – Yakov Galka Jan 02 '20 at 17:13
  • Actually, no, it shouldn't ! It would just mirror the view ray used to retrieve the view fragment position, and in the end the same previous position would get computed resulting in the same blur vector :/ –  Jan 02 '20 at 23:42
  • That's just not true. Motion blur is almost always asymmetrical, even if the depth of the fragments is the same ([example](https://upload.wikimedia.org/wikipedia/commons/a/ab/Star_Rain_in_the_Desert.jpg)). If you think that it shouldn't then there's clearly something wrong with your understanding and implementation. – Yakov Galka Jan 03 '20 at 00:28
  • Still searching to fix this. –  Jan 03 '20 at 00:47
  • As I said in my post, the blur direction remains the same, so when the vehicle rotates by 90 degrees, the blur vector is a straight line from one border of the screen to the other one (horizontally), so yeah, inverting xOffset wouldn't change anything. What you said about motion blur is right and I know that, but that's not the problem here. I've understood what you said, but I'm not sure you understood what I tried to explain. I feel the problem might come from the inverted (view * model) matrix or the previous MVP matrix. –  Jan 03 '20 at 04:35

0 Answers0