Tuesday, June 21, 2016

Between keyframes

My project this summer started with implementing keyframing for masks and layer opacity. Currently I am doing the same for transformation masks, but in between I worked on the problem of interpolation.

Layer opacity was a good test case for this. To get a smooth transition from one level of transparency to another, one would not want to manually adjust it on every single frame. Instead, we want to be able to specify a curve which the intermediary values follow.

Like most other animation software, our approach is based on cubic Bezier curves. They allow good control over the curve in an intuitive way. In fact, they can even allow a little too much control. Unless we place extra constraints, the curve could double over or form loops. The math for detecting these situations exactly can get quite complex, but luckily there is a simple compromise. If we limiting the control points between the end points on the time axis, the curve will always behave itself.

I have finished implementing the backend portion, and interpolation now works with layer opacity. The work included implementing the math, using the interpolated values in rendering the image and making the animation cache aware of which frames need to be cached separately. Right now it always defaults to a linear transition, as there is no user interface to adjust the curve yet.

We are in the process of designing a visual editor for this with feedback from animators. While the discussion is still ongoing, I believe we have established a good overall design which I can start implementing soon.

Tuesday, May 24, 2016

The work on animation features continues

While the first stable Krita version with animation is just around the corner, I am already rolling up my sleeves with plans to take the feature to the next level. It's Google Summer of Code time again.

A lot has happened since last year. Import for image sequences was added, the timeline docker was reworked and a large number of smaller changes and fixes were implemented to make the animation tools ready for inclusion in Krita 3.0. For a nice overview, check out GDQuest's video tutorial.

More will be coming this summer as I work on my second GSoC project. Firstly, animation capabilities will extend to cover most layer types. I have already started implementing it for masks and filter layers. Keyframing will become available for the filter parameters and layer opacity. However, vector layers will have to wait for now as they are facing major changes in the near future thanks to Krita's Kickstarter campaign this year, which promises to bring much needed updates to the text and vector tools.

Mockup of interpolation curve editor
Secondly, many properties, such as layer opacity, will get options for interpolation between keyframes. These could be used, for example, to animate a smooth fade-out or even do basic cut-out style animation with a transform mask. To control the interpolation, a new curve editor will complement the existing timeline.

There's a lot of work ahead, but I am already looking forward to seeing these features myself.

Tuesday, July 21, 2015

Playback and export

In the past few weeks we have been working on providing real-time preview playback for animations in Krita.

In order to deliver smooth playback, we cannot simply render the frames on the fly - that would be far too slow, especially once the number of layers starts to build up. Instead, we prerender the animation frames into a cache before playback.

I have been working on implementing the management of the playback cache. Krita now automatically prerenders the frames when it is idle, and when something changes, the affected frames are removed from the cache. To reduce memory consumption, any subsequent frames with the same content (ie. a hold) share the same cache data. The status of the cache can be seen at the top of the timeline.

In the meanwhile, Dmitry has implemented OpenGL playback support and fixed a number of bugs. He is also working on the LOD feature in the same branch.

I have also added a basic support for exporting animations into image sequences. From File -> Export animation you can choose a base file name to which Krita will add frame numbers. The frames can be exported in any image file format already supported by Krita.

In terms of central features, the animation support starting to get quite usable. However, there is still a lot of work ahead to improve stability, performance and usablility.

Sunday, June 28, 2015

Fun with onion skins

The first new feature of the GSoC project on animation in Krita is has landed in git. Until now, I have been mostly concentrating on refactoring the core structures toward their final form, which has taken much more time than I anticipated. Fortunately, it is now mostly done, and I am getting to the point where progress is more visible.

In addition to better organized code, we now have fully functioning onion skin rendering. It comes complete with independent opacities for multiple skinned frames and coloring future and past keyframes. The user interface for changing these settings is still missing, but will be coming soon. Currently the settings can be adjusted by manually tweaking Krita's configuration file.

Onion skins in action
I did a little test animation this weekend, and found the combination of proper onion skins and Krita's powerful toolset (esp. free transform tool) made it very easy to tweak and adjust my roughs. It's a joy to work with good tools. I have high hopes that animating in Krita will be a very pleasant experience.

For the adventurous among you who are itching to try it out, and know how to compile Krita, the code is available in the krita-animation-pentikainen branch. I must warn you, however, that while it is beginning to get into a semi-usable state, it's still very unstable and definitely not ready for any sort of production work. Also, files created with it will likely be incompatible with future versions.

Now that I'm at the stage of implementing new functionality, I hope to bring more frequent updates of new developments during the rest of the summer.

Monday, May 25, 2015

Hitting the ground running

Today is officially the first day of coding for this year's Google Summer of Code. For the next three months I will be working on bringing animation to Krita. There's a lot of work ahead, but I have a solid plan to work with.

Timeline docker wireframes
In addition to the implementation plan from our sprint, we have been discussing the user interface design with some of the animators among our users. Scott Petrovic has made some very nice wireframes based on these. The discussion is still ongoing and constructive feedback is always welcome.

Even though coding officially starts today, I am not starting everything from scratch. As mentioned in my previous post, I have a partially working prototype to build upon. One can already add, move, delete and duplicate keyframes on a paint layer, as well as play the animation in real time. The animation can also be saved and loaded, albeit in an experimental file format.

However, the code is still in a rough state. There are a number of major issues with it, including crashes and even data loss. Due to a number of technical shortcuts taken for the sake of faster prototyping, it is cumbersome and unintuitive to use in places. For instance, in order to play the animation, one must have visited each frame in order to populate the playback cache. In short, it's a minefield of bugs and missing features.

I will start this week by finishing a refactoring of the prototype towards the final design and looking into some of the major issues, especially one relating to data loss with undo/redo operations. Hopefully in a couple of weeks I can get to implementing new features. I for one am looking forward to seeing fully functional animation playback and onion skinning in Krita.

Monday, May 4, 2015

A summer of animation

This summer Krita is going all in for animation. Not only do we have a Google Summer of Code project focusing on it, but it will also be a major point in this year's Kickstarter campaign, alongside with major performance improvements.

There seems to be a lack of a good raster based animation software for traditional style, hand-drawn animation. Krita's excellent drawing and painting features provide a great basis for this. It is no wonder animation is a highly requested feature in Krita.

In the past couple of years, there have been several attempts to implement animation in Krita, most notably Somsubhra Bairi's GSoC project. Unfortunately none of these ever made it all the way to a fully working release. However, they have all taught us valuable lessons and I believe we now know how to finally make it work.

We have been discussing a new design with the Krita team for some months. In mid-April I had the pleasure of meeting the two main Krita developers Boudewijn and Dmitry (as well as Irina and Wolthera). During this small sprint we created a solid design for the upcoming implementation.

The focus of animation in Krita is on hand-drawn animation. That is animation consisting of individually drawn or painted frames. This is close to the traditional style of animation, only with the additional benefits of working in digital media.

However, the animation features will not be limited to hand-drawn frames. You will also be able to animate layer properties such as opacity and position, and eventually even transform mask and filter parameters. Imagine the possibilities!

I have already been working on a prototype version of the code for some weeks. While it still has some major issues, it can already be used to make simple animations, such as the one below. I will soon post more details about the status of the code and regular updates on our progress throughout the summer.


For more information on animation in Krita and the Kickstarter campaign keep and eye out for posts on the Krita website and this blog. If you want to get in touch with us, the best way to do so is through our chatroom or forums.