Whither Krita?
Moritz Moeller
realritz at virtualritz.com
Sat Sep 19 12:25:24 CEST 2009
On 09/19/2009 06:14 PM, Dmitry Kazakov wrote:
> I've thought about something like that for Krita recently. And i've got
> the following idea:
>
> All the actions on the image (except of painting) could be based on adj.
> layers. E.g. if you want to change the size of the image (or switch to a
> different colorspace), you can just add a proper layer into the stack.
> If you do not want to have an additional layer, you can merge it down.
What you describe is essentially a node based system. With nodes
arranged in a stack. Imho, any image editor is best absed on a node
based system. Wether you exposed that to the user or not is a different
question.
The advantange is: layers, layers with nested groups, sub-layers,
adjustement layers, etc. -- all the stuff an app like Photoshop offers
these days -- is a subset of the functionality of a node-based
(procedural) graph describing the image.
This also gives one resolution independece, as long as filters are
written in a way that bases anything they do on some abstract unit, a
"point", (as opposed to pixels).
Most modern high end compositing packages (Nuke, Digital Fusion, etc)
work this way. They also have powerful procedural paint ops, although
they are not geared towards natural media painting (but there is no
reason that they couldn't, its just the user base that doesn't need it).
A brush stroke is ideally recorded as a spline. That spline is converted
into a 2d spline patch mesh. Width and direction (twist) of this patch
can already be varied according to data read from the stylus when the
user paints the stroke.
All other stylus data is attached, as variables, to the control points
of the patch. It gets interpolated automatically when the patch mesh is
tessellated for rendering (in real time) and is available to any brush
engine that renders the brush.
This way you can edit brush strokes at any time, re-paint them (or
subsections of them). And what is most interesting: write brushes that
correctly antialias themselves.
The points on the tessellated patch are rectangular grids that can be
processed in a SIMD manner.
Essentially, I'm suggesting a 2D implementation of the REYES dicing &
shading pipeline for 2D brushes. Modern REYES implementations (3Delight,
PRMan), archive interactive framerates dicing & shading 3d primitives
with simpler shaders (with complexities comparable to those as would be
found in a brush).
See http://en.wikipedia.org/wiki/Reyes_rendering
The shading rate during interaction (painting) can be adjusted to the
speed of the user's system. When too slow, the brush is renderd with a
low shading rate (a "point" in brush space maps to several pixels, in
image space). When the system is idle next, the stroke is just
re-rendered with the proper (higher) shading rate. When the user zooms,
procedural brushes can re-render themseves, allowing for fractal brushes
with unlimited detail etc.
This apporach allows reolution independent brushes. It also still allows
for old school, bitmap-repetition-based brushes, by plain use of texture
maps (that are painted as decals, on the patch mesh)
The main thing from the brush writer's perspective is that the whole
thing is implicit. This means brushes have to be written as implicit
functions with no knowledge about non-local data. Proper spot sizes (for
the point [not pixel!]) for which the brush is evaluated, as well as
derivatives of any variable or even user defined function, can be made
available by the system, automagically, in an SIMD implementation of
such an engine.
Finally, SIMD = perfectly suited for multi-threading.
The brushes could be written C++ or a specialized language or a fast
enough scripting language (Lua comes to mind).
I.e. to write a brush that draws a line with a width matching the speed
the user painted with (assuming this was not mapped to width of the patch):
brush myBrush() {
/* x & y are pre-defined variables.
x runs along the length,
y along the width of the stroke
*/
float speed = getvar( "speed" ); // we assume speed it inside 0..1
float opacity = filterstep( 0.5 * ( 1 - speed ), y )
- filterstep( 0.5 * ( 1 + speed ), y );
O = foo; // O = final opacity of brush
C = O * getvar ( "color" ); // C = the final color of the brush
}
I assume filterstep() is a build-in function, doing a filtered step() of
the variable under the threshold provided as the 1st argument.
I have several ideas as to how these brushes can be rendered (to allow
e.g. smearing of the image the brush is applied to, or smearing the
brush itself). These methods can be all made transparent from the
brush-writer's perspective (aka: they don't have to care about this).
> This idea has many advantages:
> 1) We can keep design of the Krita extremely simple:
> - a small kernel for managing stack
> - a paintop kernel
> 2) All the featutures, like tranformation, CS-switch, channel-blending
> can be easily made as filters (mind! no kis_transformation_layer! its
> simply not needed)
> 3) A user will have a uniform interface(!) for all actions
> 4) At the moment, we have too much code duplication in Visitors that
> makes image/ design weird.
I agree 100%. Except for the implememtation. Instead of a stack I suggest.
1) - a small kernel dealing with managing the graph of nodes
- a paintop kernel (see above)
- brushes are nodes themselves, making use of the paintop kernel
2) - as Dmitry said. But: everything is based on points (not pixels)
and the sizes of these points are available everywhere. Raw pixel are
avaiable too, but writers of nodes/brushes are urged to make sure their
creations function properly when the mapping of points to pixels is not
1:1 (and/or the grid of points is not aligned with the grid of pixels).
There are several OSS REYES 3D implememtations that can serev as a
tutorial on how to do this. A whole bunch of transformation maths
becomes a lot simpler of course, as Krita would only need a 2D
implementation.
Examples are http://pixie.sf.net/ http://aqsis.org
There is another few posts of mine, in the archives (from 2007, I
think), where I already tried advertising these approaches. Might help
digging the resp. thread out, to understand better where I'm coming from. :)
.mm
More information about the kimageshop
mailing list