[cairo] rendering a tight mesh

Carl Worth cworth at cworth.org
Thu Aug 23 14:49:43 PDT 2007


On Thu, 23 Aug 2007 20:57:34 +0200, Tamas K Papp wrote:
> During the discussion, I learned that Cairo can't render tight meshes
> on pixmaps [1].

I'm not sure that's a fair description. But that's mostly that's
because I'm not sure what "render a tight mesh" actually means.

A more accurate description of the limitation in cairo might be
something like:

	Cairo's per-object antialiasing can lead to visible seams when
	multiple objects are drawn with identical edges.

So, sometimes there are visible "seams problems" but they arise in
different ways, and there are also various things that can be done to
avoid (or minimize) them.

>                 I am working on a plotting package, and I am thinking
> about other kind of plots, eg one in polar coordinates, where
> concentric circles and rays from the origin define areas to be colored
> with different colors.

It really depends on what you are trying to do. If the colored regions
you are drawing can be described by linear or radial gradients, then
you can use those and you won't ever get seams within the
gradients. (But sudden color transitions may lead to a lack of
antialiasing on the transition.) And obviously, there is a fairly
limited number of things that can be be described with these two
limited gradient types.

One thing I would like to see get added to cairo is a notion of a
"gradient mesh" that would let the user specify a mesh of desired
color values and cairo would smoothly interpolate among them. That
kind of thing would provide for many plotting scenarios, and would
also allow for user code to specify "path gradients" and other
effects.

But there are many other "seams" situations that aren't easily
describable as a gradient of colors. These all involve multiple
objects in one way or another. And there are various approaches that
can be used to avoid objectionable seams.

One approach is "just don't do that". That's the answer I give when
someone says they started with a white background, drew a black
circle, and then drew a white circle, and didn't like the resulting
gray ring. My argument is that users should not expect that
independently drawn shapes like that will obscure each other exactly.

Some people have objected to that answer and expect to have
"full-scene antialiasing" computing the exact result they desire. For
those people, I've suggested turning antialiasing off within cairo,
(with cairo_set_antialias and CAIRO_ANTIALIAS_NONE), and then
implementing FSAA on top of cairo's result. And we could even push
such an implementation down into cairo at some point. I've not seen
any code to do this, (but I think one user did it and found it to be
quite slow).

Another approach is to just not care about the seams, (or to be
careful about the ordering of layers and colors). For example, when I
generating a graphic for the header of my website, the first result I
had was this:

	http://cairographics.org/~cworth/images/cairo-tessellation-seams.png

The seams there were quite objectionable to me, but I just re-ordered
my polygon drawing and got this much more acceptable result:

	http://cairographics.org/~cworth/images/cairo-tessellation.png

Technically, that's probably still got plenty of seams, but it was
good enough for me, so I stopped there. The code that draw that is
available here for reference (warning, I think it was write-only
code). But the only difference between the two images swapping the
order of the poly3 and the poly5 calls.

	http://cairographics.org/~cworth/images/cairo-tessellation.c

Someone could probably even come up with a rule such as "draw light
colors over dark colors" or maybe it's the other way around. I didn't
actually figure out the rule. I just tweaked the drawing until it
looked good, (and for things that are being drawn, I think that's what
will happen in most cases---assuming that the tool used to do the
drawing has the same limitation as the final rendering).

Now, I can imagine seams being objectionable regardless of the object
order, (imagine something like a red background leaking through a
seam between two green objects). And there are ways to eliminate seams
completely even with the current code in cairo.

One way is to draw the objects in front-to-back order with the
SATURATE operator. If I'm not mistaken, that is the approach used
within gnuplot to generate this figure:

	http://gnuplot.sourceforge.net/demo_4.3/showcase_plot.3.png

I drew up a quick example of this once, (since I had never really
played with the SATURATE operator before), as follows:

	http://cairographics.org/~cworth/images/rings-seams.png

	http://cairographics.org/~cworth/images/rings-no-seams.png

	http://cairographics.org/~cworth/images/rings-no-seams.c

I think it was Alex that had originally proposed that rings
challenge. And if I recall correctly, he wasn't totally satisfied with
my solution, (though I don't recall exactly why not). And I think he's
still hoping to see an FSAA approach.

And long ago we had some detailed discussions of seams issues on this
mailing list that resulted in the following example of a different
technique than using the SATURATE operator. Here, I actually sliced a
single object into multiple pieces, drew them separately, and combined
the results without seams by using the ADD operator within a
group. This all came about because the SATURATE approach assumes that
the scene is 2.5 dimensional, (that is, there is a single depth value
that can be assigned to all objects). So this technique with ADD was
to demonstrate a seam-free approach for rendering a scene that is not
strictly 2.5D, (notice that the blue star is simultaneously in front
of and behind the red ring).

	http://cairographics.org/~cworth/images/star_and_ring-fringing.png

	http://cairographics.org/~cworth/images/star_and_ring.png

	http://cairographics.org/~cworth/images/star_and_ring.c

And Owen even described a fully automatic algorithm that could be used
for slicing up an arbitrary scene that way, (though I don't know that
anyone has ever tried implementing it, and it would likely require
some sort of BSP to be efficient):

	http://lists.freedesktop.org/archives/cairo/2005-March/003461.html

So, there's a lot of stuff in your seemingly simple "tight mesh"
question. And the right answer is that you should probably just try
what you want to do, and come and ask as you run into problems, and
we'll see what you can do. (As you can tell above, there are lots of
options with varying degrees of applicability and difficulty).

-Carl

PS. If someone wants to post the above, (rewritten to be a general
description, not a response), into a wiki page on cairographics.org
that would be appreciated.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.cairographics.org/archives/cairo/attachments/20070823/59579517/attachment.pgp 


More information about the cairo mailing list