I made a simple SIF
file containing a outline with a gradient on
it. There are strange pointy artifacts on it:
Some recent fixes to synfig have improved it a little, but the pointy things are still there:
I also made
an animated gif
(1.7MB) showing how the artifacts change when
the region changes shape.
This is a simpler .sif file which exhibits the same problem:
The black triangle shouldn't be there. It's just a bline with a gradient over it.
This is even simpler and still exhibits the same problem:
It's a single curve gradient layer, without a bline under it to mask things out.
This is the same but with a much smaller 'width', and with looping enabled. It shows better what's going on:
It turns out that the problem is in the bezier code in the ETL template library. The find_closest() function attempts to find which point on the curve is closest to each given point in the image. It does this by sampling points 1/3rd and 2/3rds of the way along the curve, and using that to decide which half of the curve to focus on next. Unfortunately in some cases this leads to the wrong answer. Here's an example - a graph of the distance of the curve from a given point against the distance along the curve. The shortest distance to the curve is almost right at the beginning, but the 2/3rds point is just closer than the 1/3rd point, so the function ends up homing in on the local minimum at 0.92:
Here's a screenshot of a java applet on a Japanese site which also gets the 'closest point' calculation wrong:
I made a quick-and-dirty fix for this. It works nicely, but is very slow. Here are the 4 images above re-rendered with the fix in place:
Before and after videos on YouTube...
I added a parameter to the curve gradient layer called 'fast', which defaults to being on, and when 'on' uses the old, fast-but-inaccurate method of drawing gradients. Here's an example of a 'fast' render. Notice the big black triangle and the rough joins in the gradient on the left:
When 'off', it uses a slower but accurate method. The black triangle has gone, and the gradient is smooth all the way around:
Unfortunately, the accurate code is quite a lot slower than the old code.