I’ve been looking for more advanced method of motion blur and this paper from ShaderX2 (http://goo.gl/ur6Z) recently caught my eye. I’m wondering if there is any way to implement this method into Unity. (Note I am using the free version, and I am thinking about going Pro, but its method of motion blur (the classic blend one frame over another) doesn’t interest me. If you cant do this method in Indie, but can in Pro, I would still like to know.)
Yes you should be able to do this. Every frame you will need to pass in a motion vector and a stretch distance to the shader for the motion blur vertex shader.
You then just perform the blur in the method described in the paper. The tricky part will be ensuring that the blur distance is correct for the given frame interval and you are operating in the correct spacial coordinate system for all operations.
I’ve been looking at motion blur methods recently, and I dismissed that one due to the fact that it really only seems to work for spheres. Are you planning on using it for something else?
Actually your kinda right about that (Note I was planning on using for much more than spheres). How does Crysis do its motion blur (That’s what I’m kinda trying to do, per object stuff.) I was quite surprised that I couldn’t find anything about how they did it? Also are there any other methods that I seem to have missed?.
What a lot of AAA games do is keep two copies of the object to world space matrix one for the current frame and one for the prior frame. Using these two matricies you can calculate trajectory between frames and stretch the objects. To make this method work for more then just static objects is more complex, your will need to keep copies of all your bone matricies so that you can render rotational movement on a per bone basis ect. The calculated velocity is then output to a ‘velocity’ buffer (using MRT) and this is used to blur the objectsi n moption. It gets very complex very quickly, but the resulting effects are quite nice. Doing this in unity would be difficult, but not impossible.
Or you can use some of the more advanced screen space motion blur that uses a heuristic based on the depth buffer to calculate the amount of blur to apply. This is talked about in GPU gems 3. This is a direct link to the article:
http://http.developer.nvidia.com/GPUGems3/gpugems3_ch27.html
If I were implementing this I would go with the screen space version but this would require unity pro.
Rosado’s approach isn’t terribly good because the blurring has to be done by averaging neighbours rather than “smearing” each pixel in the direction of movement. The latter approach would require scattered writes, which GPUs don’t really do yet.
The nicest published motion blur I’ve seen (not that I’ve looked terribly hard) is Shimizu et al.
I’m actually having trouble constructing the stretching vertex shader, though. Specifically, I’m trying to reproduce glstate.matrix.mvp. Does this look right?
objectTransform.localToWorldMatrix*
cameraTransform.worldToLocalMatrix*
cameraTransform.projectionMatrix
Because it doesn’t work. The object disappears entirely and I can’t find it any more.
Answer: the MVP matrix is actually in the order PVM, because it is left-multiplied onto the vector, which means that the right-most transformation happens first.
The other problem is that for some reason the third and fourth positions in the third row of the projection matrix need to have their signs flipped.
Thanks for answering your own question Daniel.
Let us know how the Motion Blur turns out!
Looks like you are getting down to some of the fun things in unity that are hard to debug (bring on 3.0).
As you mentioned the multiplication order it looks like you figured that out.
Is the projection a OGL vs DX issue? Due to the way the screen space setup is aligned? Have you tested on both os’s. I’ll happily run it through mine here for you on either os if you need a point of reference.
I’ve only tried it on a Mac so far, but I’ve got a windows machine for when I figure some more things out. I wouldn’t be surprised if it was different in D3D.
Unfortunately, Unity 3 wouldn’t have made the issues easier to figure out, as it was a matter of generating the glstate matrices, which can only be read by shaders.
I’ve only thought a bit about how this would be accomplished in a deferred lighting environment, but I’m sure it’s a portable enough idea.