Somewhat inspired by @EyeOdin 's question back in 2022 (here) , I decided to attempt creating a brush which draws wobbly lines in a sine wave to mixed results. Since Krita does not at this time support “ribbon” style brushes (which IMO is the primary lacking feature in Krita’s arsenal of brush engines at this moment), I went about accomplishing this using an incremental animated brush tip. (download for tip image sequence here)
In the vector animation software Animate CC, I tweened a circular brush tip oscillating vertically and exported all 50 frames of that loop as an image sequence. Importing them into Krita, I did achieve the desired effect, however, the order the frames are pasted onto the canvas in is dependent on the speed at which you are making a stroke, causing the shape to be broken when drawn at any speed faster than a snail’s pace.
This is probably caused by the line being drawn faster than the rate the screen is updated at, causing Krita to inaccurately chose which image to paste on screen when multiple variants of the same tip are expected to be drawn on the same frame. For most instances this wouldn’t matter, however for animated tips like these where it’s essential for the order to be correct, there should be an option to prioritize precision over performance.
There’s a lot of variables to consider with this (as usual given the options available!). One thing I wonder is if you have auto-spacing switched on for the preset? If so, can you test it with that switched off as it seems to interrupt the sequence.
Okay, I’ve done some quick tests with your bundle and can confirm the same behaviour on my setup. I can’t see any variables in the presets that would cause that.
I’m not sure what settings you used when saving the tips - I know there’s a few options available so could be something there. I think last time I checked there were some differences between Krita and GIMP’s dialogues for this.
Having said that - From testing, It seems like this is occurring in the pixel engine, but if you make a colour-smudge preset the sequence should render correctly. That does seem to point to an anomaly in the pixel engine, so maybe what your theory is correct?
I’m not sure who’s currently the best to ask about this. I’ll try invoking @dkazakov@Voronwe13 and @Deif_Lou and see what comes up!
It’s been a long time since I’ve worked on the engine code, but I have some potential ideas for why this might be happening. Since this is an interesting bug, I think I’ll take a look at the code and see if I can figure it out. I’m not going to make any promises, though
It looks like either the DabRenderingQueue is not properly using the sequence number to order the output correctly, or the cache isn’t using the sequence at all and just pulling whatever previously cached image is available. Easiest thing I can do to test this is to change the animated brushes to tell the system they don’t support caching.
It may take me a while to get my build system up and running, so if someone else who is regularly working on Krita wants to look at it (e.g. @dkazakov ), I think it’s just a matter of editing kis_imagepipe_brush to override supportsCaching() to return false and see if the issue still exists. I don’t think that’s a proper fix even if it works, but it will help track down the issue at least.
I added a bunch of qDebugs to investigate how the animated brushtips work, and found some difference between the implementation in the Pixel and other brush engines.
Other brush engines use KisDabCache::fetchDabCommon() to call KisImagePipeBrush::prepareForSeqNo().
In the Pixel engine, syncResourcesToSeqNo() gets called twice; once from KisDabRenderingQueue::addDab(), once from KisDabRenderingJobRunner::executeOneJob().
Apparently these jobs may get executed out of order, like this:
I just checked the bug tracker to see if anyone is already working on this, and I found a bug report for this issue from 2021 that is marked confirmed, but I don’t see any sign someone is working on it yet. I added a comment linking to this thread, so hopefully that will help if someone gets around to it.
Please pay extra attention to the animated colorsmudge brushes (do they exist actually?). The patch changes their behavior a little bit. Before the patch the first painted dab of the colorsmudge brush was the first dab of the brush. Now the first painted dab is actually the second dab of the brush. It happens because the first dab of the brush is actually used for reading a portion of data for the effect of smearing and not used for painting, i.e. colorsmudge brush actually skips painting of the first dab of any stroke.
It would also be nice to test if “filter” and “tangentnormal” still work correctly with animated brushes. From my testing it seems they do, though I’m not very sure.
On that branch, the Pixel, Color Smudge, Tangent Normal, and Filter engines all appear to behave the same (correct) way with the sequenced brushtip, with the exception of Color Smudge not painting the first dab, as was mentioned.
Example using Lilly_Mist 's rope brushtip from the thread I previously linked, painting a fast stroke: