Vector Motion Blur (Update: Now works on AMD GPU!)

Nice job! it works super fast here 170 - 200 fps, APU AMD 5800k, keep it up man!

Good work, I will follow this thread for updates!

Sorry for the slow update, I had to work for another project last month.

@martin.hedin, I have checked your file, it seems alpha blend material that cause the problem. I tried workaround this, it’s seems not possible with yet with 2.69. Blender had weird problem with it’s render sorting when using alpha blend. If two overlapped object has alpha blend material, sometimes it can cause wrong overlapped order. I use alpha blend material on the shader plane. Just FYI, Unity 3D can solves this problem by using render queue and zwrite. I hope BGE will implement that sometimes in the future.

The drawbacks of this, I try to hack the shader so only the monkeys (opaque) objects that will affected by motion blur shader. The sky (transparent) objects won’t get any motion blur effect. It seems to be tricky too, because of Render Texture alpha channel bug.

I will update again as soon as possible.

Update!
Now motion blur only works on opaque objects, but remember, you should duplicate your objects and apply material with ‘linear’ name on them. It solves problem with transparent skybox, but skybox itself won’t get any motion blur.
This shader runs a bit slower because I need to to do masking to prevent other objects to be rendered on motion blur shader. I can do that with some tricky hack. I upload two blend file, v0.7 the monkeys demo and v0.7 on martin.hedin demo.

v0.7 changes:

  • Apply mask so only object with linear depth rendered will effected with this shader
    (fix skybox transparent problem, note: you can’t use this shader on transparents objects)
  • Add transparent skybox on scene

One screenshot of On martin.hedin demo with motion blur. Notice no motion blur on skybox and water.
https://dl.dropboxusercontent.com/u/17547612/GLSL%20Experiments/screenshots/motion%20blur/mblur_on_martin.hedin.jpg

Note: On martin.hedin demo, blurred mask cause some artifacts, so I decided against using it on this demo.
https://dl.dropboxusercontent.com/u/17547612/GLSL%20Experiments/screenshots/motion%20blur/blur_mask_artifact.jpg

Happy blendering! :smiley:

I tried loading your example of 0.7 and got an error, with a crash.

“WARNING: 0:34: warning(#402) Implicit truncation of vector from size: 4 to size: 3”

No idea what it means, perhaps you do? I believe the same thing happened earlier with Martin’s “1) This does not work good with shaders, maybe you can figure out what is wrong:http://www.mediafire.com/download/me…_shaders.blend” example. I got a crash from that file but never thought to check the console after loading the standalone for errors.

Sorry to bare bad news, I’m sure it’s nothing,
TomCat

It just a warning, not an error. The problem must be something else. Maybe you can update the driver or try on another computer?

I have tested the file on AMD GPU and it works, at least the monkeys demo. It just crashed when I tried to run martin.hedin demo Maybe just because my AMD GPU is too slow, it doesn’t even run without motion blur shader.

I have updated the blend file to remove the warning. Because it’s only minor update, the link still the same, here and here.

Very cool! Impressive how you solved the problem with the alpha textures! It is actually quite fast in the standalone player! I am bit confused about how to change the aspect ratio of the camera and the filter. Do I just set all the cameras in the scene to the same? Like all to 1920 x 1080, or should this be controlled by the python script?

Thank you. :smiley:
It’s okay to change to any aspect ratio, as long as the blur pass plane still covered the camera and motion blur texture size (must be power of two) fewer than your actual render window.

Yes! Sorry, I meant to say that your example of 0.7 only crashed in Martin’s example. Your own example file works splendidly. I see now, clearly, that it is all Martin’s fault. After him lads!

I like this- it works, not as internal 2D filter and has 20 FPS in large screen.

Wow, it’s been more than a year since the last update!

Unfortunately, I have to tell you per-object motion blur on BGE is hard to implement without some hacks and performance sacrifice. ModelView matrix is actually unique per object even though it’s status as an uniform variable. ModelView matrix transform vertex/pixel from it’s local location to position relative to eye. The engine is responsible to create this matrix. John Chapman use his own engine, so it’s not a a problem. However, we can’t really do this without modifying BGE source code to save it’s per-object previous frame ModelMatrix. But you know BGE is not really in good shape for adding more features nowadays.

Yet I think it still can be possible if every object has really different material, so you can freely set prevModelMatrix on each material. But it will effect on performance, because the draw call surely will increase. I don’t know if I’m gonna implement this on BGE or not, but hey, at least I have give you the idea. :smiley:

On the side note, I actually have implement per-object motion blur on Urho3D engine, but it can’t integrated to Urho3D master because I had to hack Urho3D source engine to provide prevModelView matrix. And the hack does not cover instance rendering, which Urho3D does a lot to improve performance. You can see the thread here: http://urho3d.prophpbb.com/topic433.html

Thanks very much for your answer! I’ll try to study it (I’m not familiar with matrices) and maybe later make a try to implement a “kind” of motion blur per object/material in the bge. Thanks!

Provided that you know which camera is being rendered, you can do this in Python :slight_smile:

Hi! @agoose77: Could I ask how would you do that? (Store previous ModelView matrix… The matrix of the object we want to blur?). I still don’t understand the mechanism… Thanks! And do you know where I can find the motion blur 2D filter code in the Blender sources?

I think knowing camera isn’t enough for this kind of task. Model transformation is independent to camera. You have to properly store previous frame transformation on every objects to achieve per-object motion blur.

you can find the shader code in …\blender\source\gameengine\Rasterizer\RAS_OpenGLFilters\RAS_Blur2DFilter.h


uniform sampler2D bgl_RenderedTexture;
uniform vec2 bgl_TextureCoordinateOffset[9];
 
void main(void)
{
    vec4 sample[9];
 
    for (int i = 0; i < 9; i++)
    {
        sample[i] = texture2D(bgl_RenderedTexture,
                              gl_TexCoord[0].st + bgl_TextureCoordinateOffset[i]);
    }
 
    gl_FragColor = (sample[0] + (2.0*sample[1]) + sample[2] +
                    (2.0*sample[3]) + sample[4] + (2.0*sample[5]) +
                    sample[6] + (2.0*sample[7]) + sample[8]) / 13.0;
}

And the buffer is created in …\blender\source\gameengine\Rasterizer\RAS_OpenGLRasterizer\RAS_OpenGLRasterizer.cpp


void RAS_OpenGLRasterizer::MotionBlur()
{
    int state = GetMotionBlurState();
    float motionblurvalue;
    if (state)
    {
        motionblurvalue = GetMotionBlurValue();
        if (state==1)
        {
            //bugfix:load color buffer into accum buffer for the first time(state=1)
            glAccum(GL_LOAD, 1.0);
            SetMotionBlurState(2);
        }
        else if (motionblurvalue >= 0.0f && motionblurvalue <= 1.0f) {
            glAccum(GL_MULT, motionblurvalue);
            glAccum(GL_ACCUM, 1-motionblurvalue);
            glAccum(GL_RETURN, 1.0);
            glFlush();
        }
    }
}

@HG1: Thanks very much! I’ll take a look at that and see if I can understand the motion blur mechanism better. :slight_smile:

bg_r = int(pow(scene.world.backgroundColor[0], 1/gamma) * 255)
bg_g = int(pow(scene.world.backgroundColor[1], 1/gamma) * 255)
bg_b = int(pow(scene.world.backgroundColor[2], 1/gamma) * 255)

and now you dont need the bpy
its really just that dude. awesome stuff though. let me know when its “per object”:wink:

I need this and radial bloom in 1 pass, for a sort of “tron” light trail effect