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.
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.
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.
> 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?
You can fake gamma correct blending quite cheaply in the fragment shader. Just square the RGB values before blending them, then sqrt the result before storing it. The visual impact is significant for fast moving items, there's a higher continuity of motion.
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?
Still a great resource to make this effect with modern OpenGL. Nearly all modern games that have motion blur use a variation of the process I linked to.
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.
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.
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".
Contrast definitely matters. The highest fps experiment that I've heard of was a researcher who had people dart their eyes left and right while looking at a strobing LED. They saw separate dots instead of a continuous line at strobe rates of up to 1500-2000Hz. That's probably the top-end of visual detection for a high-contrast, high-motion video.
On the topic of _distinct_ frames... I've made a simple tool [1] that specifically generates a sequence of highly distinct frames, which can be useful to do various tests on LCD/CRT monitors.
Btw, is it okay to plug your stuff? It's my first submission to HN so I'm not yet an expert on how things work here. I just thought it was relevant, so I wanted to share...
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...
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.
Have you tried reducing the frame rate in the demo to see if the same effect is true for 30 fps as well?
Also, I wonder if a simple square is enough to prove the "sameness" of motion blurs across different framerates. A fast camera pan across a landscape may yield different results.
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.
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.
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?
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 :)
Disabling anti-aliasing is already recommended as a method to increase FPS on the Retina MacBook Pro for precisely that reason... unfortunately, the details still look ugly if you do that. Non-antialiased text also looks quite decent and is nice and sharp.
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).
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?
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).
48 comments
[ 1.9 ms ] story [ 114 ms ] threadIt'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.
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.
[1]: http://news.ycombinator.com/item?id=5211294
[2]: http://news.ycombinator.com/item?id=5211332
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.
I remember playing around with adjusting something similar to this, but it was mostly to compensate for how monitors display images.
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.
http://shurcool.wordpress.com/2011/10/06/the-effect-of-motio...
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.
[1]: https://github.com/shurcooL/RefreshRateMultitool / http://hardforum.com/showthread.php?t=1423433
Btw, is it okay to plug your stuff? It's my first submission to HN so I'm not yet an expert on how things work here. I just thought it was relevant, so I wanted to share...
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...
Also it's very, very annoying that Firefox is limited to 60Hz, that's very short sighted in my opinion.
Also, I wonder if a simple square is enough to prove the "sameness" of motion blurs across different framerates. A fast camera pan across a landscape may yield different results.
Firefox 18 on Linux, with WebGL otherwise supported.
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.
See here: http://www.gamedev.net/topic/622099-representing-interval-se...
It's the same technique that can be used to achieve Order Independent Transparency.
Screenshot: https://dl.dropbox.com/u/8554242/dmitri/projects/Conception/... 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.
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...
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?
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).
I've had crashes and blank screens running some ROME demos in Chrome here. Pretty sure it's the fancy shader use.