Blur show effect - html5 canvas - html

I want to create a blur show effect like : http://www.flasheff.com/patternsshowcase/ (FESBlur).
I've tried to use http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html using setInterval and changing the radius of the effect on each "frame", but if I set the interval delay to a lower value(increase the effect's speed), it doesn't runs smooth ( I think it's beacuse it uses imageData, and changes the value of every pixel).
Do you have any ideea about how I could make that effect to run fast enough? (about 1 second from max blur to non-blur)
Thanks,
Gabriel

I'm no expert at any of this, but some very obvious things come to mind:
Method 1: Buffering. Buffering is probably the single most effective way to stop stutters. If you could delay the initiation of the animation by .25 seconds before actually outputting it, you could probably get half of the calculations done before the animation even starts.
Method 2: Caching. The time that a blur takes to process usually grows as the radius of the blur grows. Let's say you have 20 frames in your animation. If you can cache frame 5, 10, 15, and 20 (unblurred image) then you can get frames 1-4 from blurring 5 with a small radius, and you'll get frame 5 for free, then you can get frames 6-9 from blurring 10 with a small radius, and you'll get frame 10 for free, and so on.
Method 3: Interpolation/Blending of Coarse Blurs. Blending two images should be quicker than blurring one image. If you make your animation 21 frames (1-21), then you should be able to calculate frames 1, 5, 9, 13, 17, and 21. Those frames would be free, and you'd the other frames by blending them: frame 2 (F2) would be 75% F1 and 25% F5, F3 would be 50% F1 and 50% F5, and so on.
My guess is that this would take a decent amount of tinkering on your part. None of these are going to fix your problem by simply changing a parameter or two to some magic numbers.
Realize this, however: javascript doesn't really get to pick and choose when it will or will not get the attention of the processor, and it's not exactly high on the processor's list of priorities. If the processor decides to go on vacation for 1/10th of a second, there's probably nothing that you can do to stop the stutter.

Use requestAnimFrame instead of setInterval. More info on http://paulirish.com/2011/requestanimationframe-for-smart-animating/
I tested this with faster blur reduction on my FF5 and it seems to perform fine.
(function animloop(){
blurImage();
requestAnimFrame(animloop);
})();
function blurImage(){
stackBlurImage( "image1", "output", amount, true );
amount=amount-4;
}

Related

as3 - tweenlite X coordinate approaches and gets slower

I have a rookie problem with Tweenlite. As I am playing around with it, I noticed when my animation approaches closer to its coordinate "x:100 It begins to gradually slow down. How do I make it so that from the time the object begins moving, to the very end, the speeds stays the same. Also when the object first begins movement, it starts out on a regular speed, and gradually becomes slower as its making its way.
TweenLite.to(my_box.anotherBoxInside, 5, {x:100, ease:Linear.easeNone,
onStart:myFunction, onComplete:myFunctionn});
Change ease parameter to: Power0.easeNone
TweenLite.to(my_box.anotherBoxInside, 5, {x:100, ease:Power0.easeNone, onStart:myFunction, onComplete:myFunctionn});

HTML5 video and canvas CPU optimization

I am making an app with HTML5 video along with a canvas drawing on top of it (640x480 px). The objective was to record the canvas drawing along with the encoded video to produce it as a single video. I was able to do all these using FFMPEG. But the problem I am facing is, when the HTML5 video is running it takes around 50% of my CPU. Since drawing on canvas is also demanding CPU, the browser freezes after certain time and the CPU usage for that tab on chrome is showing continously > 100. I have tried to optimize html5 canvas rendering. But nothing helped. Is there a way to run this video with much less CPU usage? or any other optimizations possible?
There is not very much you can if the hardware need to use the CPU to decode and display the video. The keyword is compromise.
A few things can be done though that removes additional barriers. These must be considered general tips though:
Efficient looping
Make sure to use requestAnimationFrame() to invoke your loop in case you aren't.
setTimeout()/setInterval() are relatively performance-heavy and cannot sync properly to the monitor refresh rate.
Reduce update load
Also if you're not already doing this: the canvas is usually updated at 60 FPS while a video is rarely above 30/29.97 FPS (in Europe 25 FPS). This means you can skip every second frame update and still show the video at optimal rate. Use a toggle to achieve this.
Video at 25 FPS will be re-synced to 30 FPS (monitors typically runs at 60 Hz even for European models which are electronically re-synced internally, which also means the browser need to deal with drop/double-frames etc. internally - nothing we can do here).
// draw video at 30 FPS
var toggle = false;
(function loop() {
toggle = !toggle;
if (toggle) { /* draw frame here */ }
requestAnimationFrame(loop);
})();
Avoid scaling of the canvas element
Make sure canvas size and CSS size is the exact same. Or put simple: don't use CSS to set the size of the canvas at all.
Disable alpha channel composition
You can disable alpha composition of the canvas in some browsers to get a little more speed. Consumer-video never come with an alpha-channel.
// disable alpha-composition of the canvas element where supported
var context = canvas.getContext("2d", {alpha: false});
Tweak settings at encoding stage
Make sure to encode the video using a balance between size and decompression load. The more a video is compressed the more need to be reconstructed, at a cost. Encode with different encoder settings to find a balance that works in your scenario.
Also consider aspects such as color-depth i.e. 16 vs 24 bit.
The H264 codec is preferable as it has wide support in various display interface hardware.
Reduce video FPS
If the content of the video allows, f.ex. there is little movement or changes, encode using 15 FPS instead of 30 FPS. If so, also use a MODULO instead of a toggle (as shown above) where you can skip 3 frames and update canvas only at the 4.:
// draw video at 15 FPS
var modToggle = 0;
(function loop() {
if (modToggle++ % 4 === 0) { /* draw frame here */ }
requestAnimationFrame(loop);
})();
Encode video at smaller source size
Encode the video at a slightly smaller size dividable by 8 (in this case I would even suggest half size 320x240 - experiment!). Then draw using the scale parameters of the drawImage() method:
context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, 640, 480);
This help reduce the amount of data needed to be loaded and decoded but will of course reduce the quality. How it turns out depends again on the content.
You can also turn off interpolation using imageSmoothingEnabled set to false on the context (note: the property need a prefix in some browsers). For this you may not want to reduce the size as much as 50% but only slightly (something like 600x420 in this case).
Note: even if you "reduce" the frame rate the canvas is still redrawn at 60 FPS, but since it doesn't do any actual work on the intermediate frames it's still off-loading the CPU/GPU giving you a less tight performance budget over-all.
Hope this gives some input.

AS3/Air drawing slows down over time

I have an Air app written in AS3 using FlashDevelop that involves using the graphics.drawEllipse method to draw 96 ellipses on the stage each frame (20fps), updating their position and alpha. After a second or so they fade out and are removed.
graphics.clear();
graphics.beginFill( color, timer );
graphics.lineStyle( 0, color, timer );
graphics.drawEllipse( x, y, r, r );
graphics.endFill();
The first 7 or so times these groups of 96 ellipses are spawned, they flow very smoothly across the screen as intended. After that they start to stutter like it's a framerate issue.
They are the only moving part in the scene and so are the only visible sign the system is struggling to draw them, but I am aware they may be the symptom rather than the cause of the slowdown. I have used the profiler and believe I have eliminated all the memory leaks.
I am wondering if anyone can see a problem with what I'm doing, or if not has any other suggestions with what could be causing the slowdown (I guess just general as3 things that could cause it).

Smoothest way to render large matrices to canvas element

I have created a dot matrix slider on a canvas element (much like the sort you get in the stock exchange). Currently I have each letter laid out as an individual matrix and then, through a succession of loops I have these letter converted into one large matrix.
I then go through and draw this matrix column by column up to a maximum amount of columns. The matrix then gets redrawn every X milliseconds, offsetting the viewable area of the matrix by one each iteration until it eventually loops. The large matrix doesn't get redrawn every time.
My issue is that the animation doesn't seem smooth at lower redraw intervals - it jumps about. I've checked the frame rate and it seems fine but occasionally it jumps and I can't work out why!
The function with the settings is right at the bottom of the JSFiddle.
dotMatrix({
animationDelay: 1000,
canvasSelector: '#dot-matrix',
dotRadius: 2,
loop: true
});
Here are some steps you could do:
Prerender each char to an off-screen canvas in a solid color on transparent background. This canvas will be used as a sprite-sheet later. Drawing a rounded rectangle is a relative expensive operation especially when you need x number of it per char.
Set up a gradient for the colors and store that too in an off-screen canvas (by now we can see memory-caching is coming to the rescue..).
Every time you update use requestAnimationFrame instead of setInterval. The latter is not able to synchronize to monitor update. Scroll delay can be calculated using the number of frames elapsed as well as the time since last update (see rAF doc for details).
For each update clear, then "blit" the letter from the sprite-sheet canvas to main canvas. When all are blitted change composite mode to source-atop and blit the gradient canvas on top, and reset composite mode to source-over (don't use save/restore - they are expensive).
In the last step you could also use composite mode copy instead of clearing canvas and using source-over, as that will remove any previous existing pixels for the area you draw to.
Hope this gives you some inputs to improve the performance.

Speed in game with libgdx

I'm making a game using libgdx. For now, every character has a speed, corresponding actually to the number of render the game wait before update the character. For example, if the character has a speed of 15, it will be updated every 15 renders. I'm conscious that this is not how it has to be done.
What is the proper way to do this? I really want to make a speed in %, for example a character will have a speed of 85%.
Use delta.
Gdx.graphics.getDeltaTime() method return secods since last render frame. Usually this value is very small, and it equal 1 / FPS.
#Override
public void render()
{
// limit it with 1/60 sec
float dt = Math.min(Gdx.graphics.getDeltaTime(), 1 / 60f);
// then move your characted according to dt
player.pos = player.pos + player.speed * dt;
// or, you could mute the speed like this:
player.pos = player.pos + player.speed * dt * 0.85;
}
When you calculate you object's next position just multiply it's speed with Gdx.graphics.getDeltaTime(), so the more time has pass since last render the more object will move. Movement speed will be constant, no matter of FPS.
However, simple solutions like this one always come with a catch! If you are i.e. moving a bullet it may happen that too much time has passed since last rendering (specially on mobile device). I.e. half of second, and for that time your bullet moved i.e. 100px and moved trough some target, but since it was never in range of detection (skipped it) target will be missed even it's not suppose to do so - player aimed well.
So, if just moving some object is not what you want, but you need that movement to be in some regular steps better way is not to multiply speed with delta time, but to repeat movement and all calculations (detections and stuff) depending on delta time. I.e.:
You have method move left(), which moves object one step and with that amount of movement everything works well.
Your method should be called 20 times per second (step takes 50mS).
You measured time since last render and it's 100mS, means that your objects need to be moved 2 steps
Don't just multiply it's speed and do one calculation - instead of that repeat whole calculation process 2 times! Call your left() method twice!
If time since last drawing is less then 50mS - then skip calculations and just draw graphics as you did in last frame.
This way you will have separated calculation rate from drawing rate. Calculation rate will be same on all devices, but drawing will depend on devices performance..