
A simple Motion Blur demo using WebGL - shurcooL
https://dl.dropbox.com/u/8554242/dmitri/projects/MotionBlurDemo/MotionBlurDemo.html
======
shurcooL
I've written about an unexpected outcome I've learned from this demo.

[http://shurcool.wordpress.com/2011/10/06/the-effect-of-
motio...](http://shurcool.wordpress.com/2011/10/06/the-effect-of-motion-blur-
on-our-perception-of-frame-rate/)

It does a lot to explain the discrepancies we often see when people argue "you
can't see more than 24 frames per second" vs. "I can tell 60 vs. 120 fps".

 _It matters how DISTINCT the frames are._

~~~
Scene_Cast2
I was actually thinking about motion over the past few days. High frame rate
does matter, but it's for a different reason. Human eyes can track objects
extremely well.

Here's a simple test to do with the demo. Try tracking that motion-blurred
cube on the left with your eyes - it's all blurry. Now, try tracking the one
on the right - it will be sharp, but "jumpy". Now, try tracking the one on the
right with your 120Hz monitor - the motion should be MUCH smoother - and
that's where the need for high frame rates comes in. The higher the frame
rate, the better the object will look when you're tracking it with your eyes.

Ideally, if we only account for objects travelling across the screen in 2
seconds, and a screen is ~2000 pixels wide, and we want to have an error of
<=1 pixel, then theoretically, we need (2000px)/(2sec) = 1000 Hz frame rate
for high motion realism. Unfortunately, I don't see it coming anytime soon...

~~~
nviennot
So if the screen is really dense, say 20000px wide, you would need a 10kHz
refresh rate. That contradict the contrast experiment.

~~~
Scene_Cast2
In order to keep the increase in sharpness that you get from 10x the pixels -
yes, you would need 10kHz, 10x the refresh rate. The moving picture would look
sharper than the moving picture on the 2000px display. If you use 1000Hz
refresh rate, then the crispness of moving objects on the 20,000px display
would degrade to approximately the crispness of the 2,000px display. I hope
that made sense.

------
kingfishr
Great demo!

This is probably obvious, but for the first time it occurs to me that motion
blur is essentially the same as anti-aliasing. They are eye-tricking hacks to
work around a lack of resolution in the medium -- screen resolution, in the
case of pixel anti-aliasing, or "time" (framerate) resolution in the case of
motion blur.

Recently I've been wondering if as very high-resolution displays become
commonplace, anti-aliasing will become obsolete. If I could play an FPS video
game on a 500dps monitor, would anti-aliasing make any perceptible difference?
At some pixel pitch, even text anti-aliasing won't matter.

The same thing seems to apply here. If we had 5000Hz screens (and could run
our animations quickly enough to keep up), would applying artificial motion
blur buy you anything?

~~~
GuiA
Those are some extremely insightful and promising thoughts that deserve more
research. If you venture more in those explorations, I'd love to read thoughts
you have :)

------
shurcooL
If there's enough interest, I can share the original C++/OpenGL code (with
Xcode project in latest version, MSVC project in older code).

The problem is that I doubt the code has much value, because the C++/GLSL code
does a very poor job of communicating the higher-level abstractions that are
going on, and the documentation is nonexistent because I was just doing it as
a demo.

In other words, it's not very reusable nor is it easy to learn from. :( Its
main value is the running demo.

This problem is one of the things that inspired me to work on my current
project which tries to make code/functionality/value more reusable by default
(i.e. with less extra effort on your part).

------
overgard
Tastefully done! The one thing about motion blur I've seen is almost everyone
overdoes it. You got just about the right level where it looks natural and not
gaudy.

~~~
shurcooL
Thanks. :)

It's likely because I don't fake the motion blur effect as it is most commonly
done (nothing wrong with that, I'm just describing it). Instead, I calculate
what your eyes would realistically see. I render the triangle with a non-zero
exposure time (the exposure time is equal to the duration of 1 frame).

There are definitely some shortcuts and approximations taken (I don't
compensate for how CRT/LCD displays display images, no colour correction,
etc.), but the "big picture" is 100% based on real physics.

The motion blur is calculated with the assumption you keep your eyes still. If
you track the moving square, then by definition there should be zero motion
blur (if your display were perfect). However, it still looks okay with motion
blur even if you track the square.

~~~
Arelius
> but the "big picture" is 100% based on real physics.

Having implemented motion blur numerous times, this is actually super
interesting to me. However I was reading through your source-code and was
having a hard time following along. Any chance you could explain what the
physical models you are basing your algorithm on and how that ended up
translating to code?

Thanks.

~~~
shurcooL
First I'll link you to these two replies [1][2]. I can go in more detail if
you'd like.

[1]: <http://news.ycombinator.com/item?id=5211294>

[2]: <http://news.ycombinator.com/item?id=5211332>

------
lambda
Crashes the whole phone if I run it under Firefox on Android. I should
probably report that, any crashing bug is a potential security vulnerability.

~~~
shurcooL
Sorry about that. I wrote the web code quite sloppily, and it was my first
time. I just wanted to port my native C++/OpenGL code to the web.

~~~
lambda
Not your fault. If it crashes the whole phone, that's a bug in Firefox and/or
Android. A Web app should never be able to crash the browser, and the browser
shouldn't be able to crash the phone.

------
JoshTriplett
Gives an alert as soon as I run it: 0:15(87): error: Arrays cannot be out or
inout parameters in GLSL 1.10

Firefox 18 on Linux, with WebGL otherwise supported.

------
petekp
Feels great to my eyes. The non-blurred square looks far choppier and eye-
straining by comparison. Would love to be able to easily add this effect to
CSS3 animations since it'll probably be awhile (3-ish years?) before WebGL is
more commonplace.

~~~
shurcooL
I thought so too, so I wanted to experiment with applying the same type of
(physically-accurate) motion blur to scrolling text.

Screenshot:
[https://dl.dropbox.com/u/8554242/dmitri/projects/Conception/...](https://dl.dropbox.com/u/8554242/dmitri/projects/Conception/images/Scrolling%20Motion%20Blur%201.png)
Source: <https://github.com/shurcooL/Conception/tree/motion-blur>

I've realized the effect in motion looks quite nice, but it HAS to run at full
60 FPS at all times. If there are dips in the framerate, the effect is
horrible (partly because the 16.66 ms number is hardcoded rather than
calculated). My implementation is very naive and not optimized, but it funs
well with a dedicated card. Not so much with Intel 3000. It was just a mockup
so I didn't develop it further for now.

------
PavlovsCat
How does this work? It's way too fast for me to see anything, other than that
it looks great; what is the difference between this and, say, drawing a lots
of transparent rectangles lerped between current and last position?

~~~
shurcooL
It's simple conceptually: I just draw a quad with non-zero exposure time.

For each pixel, I calculate how much exposure it receives during the last
1/60th of a second (assuming it runs at 60 FPS). So, if a pixel is backed by
the triangle for 100%, it gets the full colour. If it's only 24% of the time,
then it's 24% of the full colour, etc.

That's what happens conceptually. In order for it to run faster, I have to
optimize the solution and basically calculate the same result, but by drawing
some triangles and calculating some distances... It's hard to explain, but
it's nothing more than an optimization.

~~~
virtualritz
You can make it look even better by adding support for shutter (in)efficiency:
<http://www.dctsystems.co.uk/Text/ShutterPresentation.pdf> resp.
<http://www.dctsystems.co.uk/Text/shutter.pdf>

~~~
shurcooL
This is very interesting. I'm very curious how this relates to the human eye.

I remember playing around with adjusting something similar to this, but it was
mostly to compensate for how monitors display images.

~~~
virtualritz
Shutters with an efficiency between 75% and 50% just look more natural, from
my experience.

The stuff proposed in this papers made it into blockbuster VFX production
renderers ca. 2005 (3Delight) and 2007 (Pixar's PhotorRealistic RenderMan).

There is no information available on what full CG features use this. However,
when you look at a still frame that exhibits heavy motion blur in isolation,
you can usually tell right away if a perfect of imperfect shutter model was
used. The latter looks smoother/more natural.

As far as VFX in live action films go: it makes sense to match the virtual
shutter to the one of the camera that was used to shoot the footage the VFX
need to be integrated with.

The high end offline rendering plug-in, my company produces, has a setting for
this. The default we use (and that most of our customers leave untouched, I
believe) is 75% shutter efficiency.

------
donutdan4114
Looks good. Shocking amount of code to achieve that effect though.

~~~
chii
its actually pretty "short" me thinks.

------
maaku
Doesn't this only work because the square is a uniform color?

~~~
shurcooL
Yes, the existing code could not handle overlapping objects of different
colours, nor textured objects.

However, in theory, the technique and code can be extended to handle those
cases. It's just more demanding computationly-wise.

Adding overlapping objects of different colours is somewhat easier (but still
hard) than adding textures.

~~~
shurcooL
To make overlapping geometry possible, UAVs could be used.

See here: [http://www.gamedev.net/topic/622099-representing-interval-
se...](http://www.gamedev.net/topic/622099-representing-interval-set-with-
values-for-pixel-values/)

It's the same technique that can be used to achieve Order Independent
Transparency.

------
throw_away_acc
Well done and nice to see that some understood that motion blur is more
important than just high fps.

------
caffeineninja
After looking at the code, not sure if I would use the word 'simple'. Well
done.

------
blake8086
Could you do this with the system mouse cursor?

~~~
shurcooL
In an open source operating system, it could be done.

------
Detrus
On MBP i5 works in Firefox but shows white screen with no console errors in
Chrome.

~~~
shurcooL
That's strange, I developed it by testing in Chrome first, Firefox second. It
has always worked for me in Chrome on all computers I've tried. Which version
of Chrome do you have?

~~~
Detrus
Chrome 24.0.1312.57 on OSX 10.6.8 MBP i5.

I've had crashes and blank screens running some ROME demos in Chrome here.
Pretty sure it's the fancy shader use.

~~~
shurcooL
That's the exact same version of Chrome I have running on my 2011 MBP with
10.8.2. Either there's something up with your video card, Chrome install, or
maybe Snow Leopard is to blame (no idea why).

------
camus
doesnt work here , what is it supposed to do ? (latest chrome)

~~~
shurcooL
Move your mouse, and the two squares should follow. Left one with motion blur,
right one without.

In motion it looks something like this (but you can't convey the effect with a
screenshot, you need to see it live):
[https://dl.dropbox.com/u/8554242/dmitri/projects/MotionBlurD...](https://dl.dropbox.com/u/8554242/dmitri/projects/MotionBlurDemo/MotionBlurDemo.png)

