Filter effects - blur test
Here is the first test on rendering filter effects. It applies constant gaussian blur to every rendered object of type NRArenaShape. This is mostly to test the speed of rendering filter effects in real time.
This test does not apply blurring to all types of objects - that would result in blurring the object, blurring the layer the (already blurred) object is on, etc.
The biggest problem at the moment seems to be transparent areas appearing, when an object is drawn in several smaller pieces rather than in one piece. Guess the object needs to be drawn on a larger buffer thet is larger than the result will be - thus allowing blurring to take in to account the pixels outside the actual area, we are rendering to.
On 5/30/06, Niko Kiirala <niko@...1267...> wrote:
Here is the first test on rendering filter effects. It applies constant gaussian blur to every rendered object of type NRArenaShape. This is mostly to test the speed of rendering filter effects in real time.
Thanks, that's a great start!
I have given you (kiirala on SF) SVN access and created a branch for filter effects, check out with:
svn checkout https://svn.sourceforge.net/svnroot/inkscape/inkscape/branches/svg-filters <dir>
and please commit your change to it.
Hugo, now it's your turn :) Please use this branch also for your part of the work.
This test does not apply blurring to all types of objects - that would result in blurring the object, blurring the layer the (already blurred) object is on, etc.
Right. Later we'll blur any kind object for which the filter is specified, but for testing it's OK.
The biggest problem at the moment seems to be transparent areas appearing, when an object is drawn in several smaller pieces rather than in one piece. Guess the object needs to be drawn on a larger buffer thet is larger than the result will be - thus allowing blurring to take in to account the pixels outside the actual area, we are rendering to.
Another related problem is that the blurred edges are cut off by the bbox of the object. So, blurring must extend the rendering bbox of NRArenaItems by its deviation radius, so that it covers all of the blurred object.
As for rendering in stripes, yes, we may want to disable this for those objects that have filters applied. Another solution might be to extend the stripes and make them overlap, also by the deviation radius. I don't know which is easier to implement and which is faster; please experiment.
For the purpose of testing, could you please make the blur effect take the radius from the same filtertest prefs value, instead of the fixed value of 2?
More importantly, I noticed that the radius is interpreted in screen pixels, i.e. it stays the same (and therefore changes relative to the size of the object) when you zoom in or out. I think this is incorrect: the spec says that with userSpaceOnUse (which is the basic mode we should strive to implement), the lengths are interpreted in the local coordinate system, which includes zoom. In other words, the lengths must be considered to be in px units, not screen pixels, and you need to pass the current display transform (i.e. zoom, but later it may include not only zoom but also e.g. rotation) to the filter and make the filter multiply its lengths by the zoom factor.
As for speed, I noticed you have an operation with a double (sum) in the innermost loop. I think it might become noticeably faster if you implement this critical calculation entirely in integers. Can you do this?
And finally, can you please resend that diagram you sent a couple days ago but in SVG? I don't have Dia :)
Thanks again, and please keep the great work! I'm watching the filters branch with great excitement :)
On May 30, 2006, at 9:01 AM, bulia byak wrote:
As for speed, I noticed you have an operation with a double (sum) in the innermost loop. I think it might become noticeably faster if you implement this critical calculation entirely in integers. Can you do this?
Oh, just be sure to measure performance before and after things like this (and with and without optimization turned on).
With the introduction of the Pentium processor many operations became faster with floating point than with integer. So one needs to actually measure things like this.
(not measuring performance of changes intended to speed things is an easy trap to fall in, but studies have shown that programmer intuition in regards to optimization is wrong the vast majority of the time)
On 5/30/06, Niko Kiirala <niko@...1267...> wrote:
Here is the first test on rendering filter effects. It applies constant gaussian blur to every rendered object of type NRArenaShape. This is mostly to test the speed of rendering filter effects in real time.
Hi, First post to the list, and I want to thank everyone that makes Inkscape such a great app.
Just an idea here : would it be possible to create an object with blurring properties (as well as a certain amount of transparency) on the objects below it?
That could have very interesting application for artistic drawing (simulate a piece of glass, a lens , etc). Even though the same result could be done by applying a blur effect on a certain area, this would make it far more souple (one could freely move the object, resize it, etc...
Just an idea (and I'm not a programmer, so I can't do it :) )
Cheers, Loïc
Hi Niko,
Now that blurring works fine, I think next up is some rearchitecturing in your part. You are creating and deleting the filter object twice per each call to nr_arena_item_render, once to get the extent from it and then to do the actual render. This is inefficient. I think filter object must be a property of NRArenaItem, created upon demand (i.e. on first render) and then reused for all subsequent renders of that item.
Similarly, gaussian blur filter should create its x and y kernels on demand and not regenerate them upon each render.
However, we need to update the filter if some of its parameters change, and we need to get the list of filter primitives and their parameters to create it in the first place. All you have at the NRArena level is a (copy of) object's SPStyle - it's in the subclasses of arena item (shape and glyphs), but to get from the href in the filter property to the actual structure and values, you need some additional interfaces. Hugo & Niko, did you give any thought to it? Did you study how this is solved for gradients? Niko, did you check out Hugo's initial SPFilter code? Please share your thoughts.
Niko,
One more thing. Is it possible to make the gaussian blur to use a single pass for both horizontal and vertical blurring, and correspondingly to use only one temp buffer instead of two? This should make it noticeably faster and use less memory.
On 6/2/06, bulia byak <buliabyak@...400...> wrote:
Niko,
One more thing. Is it possible to make the gaussian blur to use a single pass for both horizontal and vertical blurring, and correspondingly to use only one temp buffer instead of two? This should make it noticeably faster and use less memory.
Hmm, ignore this. I've read up on the topic of blurring and it seems that the two-pass method you're using is actually faster :)
On Fri, 2 Jun 2006 16:49:00 -0400 "bulia byak" <buliabyak@...400...> wrote:
Now that blurring works fine, I think next up is some rearchitecturing in your part. You are creating and deleting the filter object twice per each call to nr_arena_item_render, once to get the extent from it and then to do the actual render. This is inefficient. I think filter object must be a property of NRArenaItem, created upon demand (i.e. on first render) and then reused for all subsequent renders of that item.
Not only that is inefficient, but stops us from having any sensible way to setting filter parameters. My original plan was, that NRArenaItem would contain a pointer to filter it uses (or null pointer, if it doesn't use filtering) Having the filter object created just before rendering is merely a cheap imitation of that.
Similarly, gaussian blur filter should create its x and y kernels on demand and not regenerate them upon each render.
Well, that's so-so. It might be a bit faster, but it would use quite a bit more memory, while it is not rendering and complicate memory management inside filters.
However, we need to update the filter if some of its parameters change, and we need to get the list of filter primitives and their parameters to create it in the first place. All you have at the NRArena level is a (copy of) object's SPStyle - it's in the subclasses of arena item (shape and glyphs), but to get from the href in the filter property to the actual structure and values, you need some additional interfaces. Hugo & Niko, did you give any thought to it? Did you study how this is solved for gradients? Niko, did you check out Hugo's initial SPFilter code? Please share your thoughts.
I've given that plenty of thought. Though didn't pass my mind, that gradients do much the same, that we would need here. Have to take a look there.
I just committed a new blurring code which works much faster by using subsampling and linear interpolation. Of course this is somewhat at the expense of quality, but I think the quality is still acceptable, yet now it renders with tolerable speed, even at high zooms, which makes blur actually usable. (Check it out in the svg-filters branch!)
I think eventually we'll need to provide a user option to set the level of subsampling to accommodate different hardware performance, as well as to make sure it's turned off during bitmap export, for maximum quality of the exported image.
participants (4)
-
bulia byak
-
Jon A. Cruz
-
Loïc Martin
-
Niko Kiirala