Advertisement

"Real-Time" Smoothing

Started by January 19, 2016 02:50 AM
12 comments, last by l0calh05t 9 years ago

Store your average and history length (though you won't be storing a history). Initialise it something like average = 30, historyLength = 5.

When you get a new value you add it to your average which is fairly easy to do:

average = (average*historyLength+newValue)/(historyLength+1);

historyLength++;

But now your history length has increase too so you need to drop an old value which can be done like

average = average*(historyLength-1)/(historyLength - 1)

historyLength--;

But because of how averages work, the average won't change from dropping an 'average value' so you just need to decrement historyLength but since you just incremented it you can simply not increment it to begin with leaving you with just:

average = (average*historyLength+newValue)/(historyLength+1);

The larger the value you choose for history length the less susceptible it is to sudden changes, lower values will be more responsive. It will probably take a very long time to converge if at all.

Here's an example of how it works (image). The blue is the raw values, the red is a long history (20), the yellow is a shorter history (2).

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

Hey @L.Spiro, did you find what you were looking for? It would be very interesting and helpful if you were to post your solution (or workaround) :-)

Advertisement

What Nanoha posted seems to be the most suitable for me currently, and I believe it was what was in my notebook that I tossed.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Store your average and history length (though you won't be storing a history). Initialise it something like average = 30, historyLength = 5.

When you get a new value you add it to your average which is fairly easy to do:

average = (average*historyLength+newValue)/(historyLength+1);

historyLength++;

But now your history length has increase too so you need to drop an old value which can be done like

average = average*(historyLength-1)/(historyLength - 1)

historyLength--;

But because of how averages work, the average won't change from dropping an 'average value' so you just need to decrement historyLength but since you just incremented it you can simply not increment it to begin with leaving you with just:

average = (average*historyLength+newValue)/(historyLength+1);

The larger the value you choose for history length the less susceptible it is to sudden changes, lower values will be more responsive. It will probably take a very long time to converge if at all.

Here's an example of how it works (image). The blue is the raw values, the red is a long history (20), the yellow is a shorter history (2).

This is just a convoluted (pun not intended) way of describing a single pole filter (see Daixiwen's post) with k = 1/(historyLength+1) and an initial value of y[0] = 30.

In any case, if you want to prevent switching back and forth between two methods you probably want to apply hysteresis. I.e., activate optimization if (smoothed) frame time is greater than target frame time +k/2 (where k is the hysteresis constant) but deactivate them only if the (smoothed) frame time is reduced to less than target frame time -k/2.

This topic is closed to new replies.

Advertisement