From: Michael D. <md...@st...> - 2013-03-07 14:50:06
|
On 03/07/2013 04:41 AM, Phil Elson wrote: > > Would this greatly slow down the rendering? > > That is a million dollar question. Without trying it to see, we could > ask the agg mailing list to see if they have any insight. > Personally I'd be surprised if anything we did at the Agg level was a > bottleneck given how much python code comes before it - though I admit > that doesn't mean anything in practice... At first glance, I would be concerned about how this scales with the number of paths (well, the number of vertices, really). With regular path rendering in Agg, the time grows exponentially with the number of vertices in the path, which is why we've put so much effort into path simplification etc. If we use this to render a contour with many levels, does it start to break down at some point? > > > > I wonder, though, and the SVG article you link to hints at this, if > we wouldn't be better off just upsampling our Agg rendering instead. > > ... > > I put together a very quick hack on my agg-upsampling branch, which > hardcodes the upsampling to 2x in each direction. > > I'm not a big fan of supersampling > (http://en.wikipedia.org/wiki/Supersample_anti-aliasing) - that is > essentially implementing a global anti-aliasing scheme which one > wouldn't be able to control on an artist by artist basis (such as > fonts) with the overhead cost of increasing the memory highwater by a > factor of 5 (as you say for an image of size (n, m) at a minimum the > drawing buffer needs to be (2n x 2m) + then downsampled to (n x m)). The last buffer can in many cases be done in the GPU, so there isn't necessarily an additional main memory buffer... But that's a minor point. > We might even want to upscale to a factor of 3 or 4 to really get rid > of most of the white in this example. Maybe it would be useful to quantify the amount of error between the two approaches. At a certain point, it gets below the level of perception and we can probably say it's "good enough". While I understand the performance implications, I like the fact that it is bounded. > > > From the linked SVG article: > > Perfect antialiasing can be done by rendering complete artwork at a > much higher resolution and subsequent downsampling. > > I also dispute this claim. Whilst good anti-aliasing can be achieved > using supersampling, I believe /no matter the size of your bigger draw > buffer /you will always get a component of background color (white in > our case) which goes into the averaging operation and therefore will > impact the final pixel color. It is then a compromise between > performance vs "good enough" rendering. I agree. It's perhaps worth determining how much worse it is and how good is "good enough". > > > Having said all of the above, supersampling would be a nice feature to > add to mpl's Agg backends (and maybe the Cairo backend too) - though I > do not believe it is a full solution to this problem. I think we agree there is a tradeoff here. On the one hand, there is a mathematically perfect solution that requires some rather pervasive refactoring of the code and permanent care in how plots are constructed to ensure it's running optimally, and an exponentially growing performance curve as the complexity of the plot increases. On the other, is a suboptimal end result that requires minimal changes, and a well-defined and upper bound performance penalty. I think to really determine where on the tradeoff we want to be, some more experiments comparing the quality of the end result of the two approaches would be helpful. Mike > > Cheers, > > > > > > > > > > > > > On 7 March 2013 09:15, Phil Elson <pel...@gm... > <mailto:pel...@gm...>> wrote: > > > I'm trying to compile your examples, but it seems perhaps you > forget to include a file > > Sorry, you can find pixel_formats.h in the examples directory. I > have a mirror of agg here: > https://github.com/pelson/antigrain/tree/master/agg-2.4/examples > > My compile steps are: > > export AGG_DIR=<path to antigrain checkout> > > g++ -c -O3 -I${AGG_DIR}/include -I${AGG_DIR}/examples > -L${AGG_DIR}/src basic_path.cpp -o basic_path.o > g++ -O3 -I${AGG_DIR}/include -L${AGG_DIR}/src basic_path.o -o > basic_path -lagg > > > > I had played with the "compound renderer" example in Agg some > years ago, but couldn't really understand how it worked > > Agreed. It took the best part of a day to figure out how to do it, > given no prior knowledge of Agg. I intend to submit a couple of > simpler (GUI-less) examples to be included with the agg repo - and > perhaps even write some documentation for this stuff! > > > > Does it work with alpha < 1? > > Yes. I've attached the two images (converted from ppm to png using > gimp + default settings) so that you can see the results. Each > shape has an alpha value of 200. > > Inline images 1Inline images 2 > > HTH > > > > > > On 6 March 2013 20:27, Michael Droettboom <md...@st... > <mailto:md...@st...>> wrote: > > I'm trying to compile your examples, but it seems perhaps you > forget to include a file -- pixel_formats.hpp? It's not in > the agg24 source tree. > > Mike > > > On 03/06/2013 12:06 PM, Phil Elson wrote: >> Smart rendering of adjacent, anti-aliased patches is a >> question which has come up a couple of times in various >> guises in the past. >> It is my understanding that the lack of this functionality >> led us to disable anti-aliasing for contouring and is the >> reason the following image has a white stripe around the >> circle where there should be just a nice blend of the two colors: >> >> >> import matplotlib.pyplot as plt >> import numpy as np >> import matplotlib.patches as mpatches >> import matplotlib.path as mpath >> import matplotlib.collections as mcol >> >> >> # create two paths. One a circle, the other >> # a square with the same circle cut out. >> x = np.linspace(0, np.pi * 2, 1000) >> >> circle_coords = np.array(zip(*[np.sin(x) * 0.8, np.cos(x) * >> 0.8])) >> pth_circle = mpath.Path(circle_coords) >> >> sqr_codes = np.repeat(mpath.Path.MOVETO, len(circle_coords) + 5) >> sqr_codes[1:5] = mpath.Path.LINETO >> sqr_codes[6:] = mpath.Path.LINETO >> sqr_coords = np.concatenate([[[-1, -1], [-1, 1], [1, 1], [1, >> -1], [-1, -1]], >> circle_coords[::-1]], axis=0) >> sqr_path = mpath.Path(sqr_coords, sqr_codes) >> >> >> ax = plt.axes() >> patches = [mpatches.PathPatch(pth_circle), >> mpatches.PathPatch(sqr_path)] >> col = mcol.PatchCollection(patches, >> antialiaseds=True, >> edgecolors='none', >> facecolors=[(0, 0.0, 0.0, 0.9), (0.1, 0.1, 0.02, 0.9)]) >> ax.add_collection(col) >> ax.set_xlim([-1, 1]) >> ax.set_ylim([-1, 1]) >> plt.show() >> >> >> >> I know of lots of the workarounds for this (turn off AA, turn >> on lines, extend the path slightly, set a dark background >> color) all of which have down-sides, so I'm keen to find a >> final solution to the problem. >> >> When the two patches marry up perfectly with full >> anti-aliasing, the antigrain (AGG) community call this >> "flash" or compound rendering, and this capability was added >> to Agg 2.4 (which we already ship with mpl). >> >> In order to make full use of the compound rendering technique >> I believe the drawing pipeline in "_backend_agg.cpp" would >> need to change, which could be problematic. A less >> wide-impacting alternative would be to draw all "patches" of >> a single Collection in the same rasterization step (i.e. just >> change _draw_path_collection_generic), though this does mean >> that, as it stands, the result of plt.contourf would not be >> able to make use of this new functionality - a MEP which >> changes the return type of plt.contourf to a single >> Collection might be able to fix that. >> >> I've put together a simple example similar to this in C++ >> using agg (no mpl changes yet), showing the differences in >> the code needed between the old technique vs the "new" >> compound renderer (attached). >> >> >> Ok, so the question to those that have knowledge of the >> _backend_agg.cpp code (Mike, Eric, JJ + others?): >> >> * Have you already looked at doing this and determined that >> this is a non-starter? >> * Do you support adding the ability for the agg backend to >> draw compound artists (i.e. Collections) in this way >> rather than treating them as individual primitives in the >> canvas? >> * Since many of the other backends can't do flash >> rendering, would we even want to make this change? >> o SVG in Firefox 10.0.2 has the same problem, it is >> discussed slightly more in >> http://www.svgopen.org/2002/papers/sorotokin__svg_secrets/ >> o Acroread has the same problem with PDFs, only to a >> much lesser extent than in the PNG attached >> >> >> Thoughts? >> >> >> >> >> >> >> >> >> >> >> >> >> ------------------------------------------------------------------------------ >> Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester >> Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the >> endpoint security space. For insight on selecting the right partner to >> tackle endpoint security challenges, access the full report. >> http://p.sf.net/sfu/symantec-dev2dev >> >> >> _______________________________________________ >> Matplotlib-devel mailing list >> Mat...@li... <mailto:Mat...@li...> >> https://lists.sourceforge.net/lists/listinfo/matplotlib-devel > > > ------------------------------------------------------------------------------ > Symantec Endpoint Protection 12 positioned as A LEADER in The > Forrester > Wave(TM): Endpoint Security, Q1 2013 and "remains a good > choice" in the > endpoint security space. For insight on selecting the right > partner to > tackle endpoint security challenges, access the full report. > http://p.sf.net/sfu/symantec-dev2dev > _______________________________________________ > Matplotlib-devel mailing list > Mat...@li... > <mailto:Mat...@li...> > https://lists.sourceforge.net/lists/listinfo/matplotlib-devel > > > |