First alpha of my GSoC project: procedural texture generator

This is a great start. It already seems to be working really well.

I think the first thing that would be neat is a better way to access examples of some possibilities. I did see they do have an “Expression Browser” file where you can choose from pre-made options. That would be neat to add it to the UI so people can more of these expressions in action.

Not sure how hard that would be to hook up. In terms of populating it with examples, I wonder if we could use the ones on the site and copy/paste them?

I guess in terms of figuring out new ones, this field would be called “procedural textures” if someone would want to do research? I see there is some built-in auto-complete for the API. One thing that would be nice is having a documentation page with the available API that people can use. Not sure if it would be easier to reference another site for understanding this. Maybe a link like this…

Or maybe we should do our own documentation. I see a developer tutorial section on their site, but that seems to be targeted toward people that are writing C++ applications using it. We might need to write a bit of our own that is more artist friendly to put on The Disney page is definitely designed more for programmer consumption than artist consumption.

1 Like

This is great! It was fun and quick to make for instance a water pattern! :grin:

One thing I wish was different is that when I changed from SeExpr to Simplex Noise, I lost my original water test on SeExpr, I would love for it to remember the changes so when I go back to SeExpr it is back to how I left it. Or a little warning telling me that I will lose my changes if I change mode, and ask me if I’m sure if I want to change.

Great work on this so far! :grin: Excited to see it developed further!

The examples on the site are Apache 2.0 licensed, so they can be freely copied.
As for the documentation, not even RenderMan has a custom page, so I think we’ll have to write one.
Autocompletion - I’m going to start working on tidying up the widgets (cc @deevad, I’m going to need your advice here), and extracting the strings for translation.

I’m just curious but are the textures you create this way stored somewhere for easy access when they are needed or is it necessary to always generate them as a fill layer?

So far, they are generated as part of a Fill layer.
A TODO in my list is to turn the scripts into resources (like brushes and patterns).


Hi all!

This is the second alpha of my SeExpr project. Releases are available here:

Integrity hashes:

114ae155fb682645682dda8d3d19a0b82a4646b7732b42ccf805178a38a61cd0  krita-4.3.1-alpha-cff8314-x86_64.appimage

In this release, I fixed the following bugs:

  • @Deevad’s issue with AZERTY keypad presses. They were previously considered by the SeExpr editor widget as Ctrl-keys for the autocompletion :woman_facepalming:
  • Uncompressed the editor widgets, and let them have their native values (thanks @Deevad)
  • Pasting on the editor breaks the formatting
  • Emmet O’Neill reported that there wasn’t any autoupdate on editing the script. I added a signal from the SeExpr code and a progress updater to the Layers docker.


  • I sorted a lot of the SeExpr code, hiding unnecessary features (like two Disney-internal UI widgets) and legacy UI (a grapher that uses Qt4’s QGLWidget) behind feature flags.
  • Reworked the CMake scripts to make use of imported targets.

These two changes allowed me to drop some CMake hackery from the Krita side of things.

@Rakurri’s issue on losing the configuration has been reported as bug 422885. I added the necessary calls to the SeExpr dialog code; however, the dialog restore is trumped by the configuration reset that’s done by the Fill Layer dialog itself.

Next, I plan to review the resources code and try my hand at adding SeExpr scripts to them. But I need some rest, this last term is pretty heavy in terms of homework.

Please test, and let me know what you think!


So… I’ve had some luck porting an OSL (blender’s open shading language) node into this:

$vec = [$u, $v, 0];
$radius = 0.5;
$color1 = [0,0,0];
$color2 = [1,1,1];
$size = 8;
$offset = 0.5;

#tiling part.
$tiles = $vec * size;
$repeat = boxstep(1 , fmod($tiles[1] , 2.0) ) *offset;
$tiles = [$tiles[0] + $repeat, $tiles[1], 0];
$tiles -= floor($tiles);

#circle determining part
$dist = $tiles - [0.5, 0.5, 0];
$dotproduct = dot(dist, dist) * 4;
$fac = smoothstep($radius*0.99, $radius*1.01, $dotproduct);

#filling the circle, we only want to use color interpolation if we're sure our circle factor is above 0
if ($fac>0) {
  $color = ccurve($fac,0,$color1,4,1,$color2,4);
} else {
  $color = $color2;

# Return the color.

Right now, I am mostly wishing for…

  1. The comment color to not be so close to the color for the variables
  2. An indication of which line is ‘erroring’ would be super duper helpful.
1 Like

The comment color to not be so close to the color for the variables

Will be fixed ASAP. Thanks @wolthera!

An indication of which line is ‘erroring’ would be super duper helpful.

I had thought SeExpr’s editor widget already bundled error reporting, but it seems it doesn’t…

Putting this here: Procedural texture generator (example and wishes)

Would it be possible to have some set of presets patterns that will tell the user about the code. some of the user might not be that knowledgeable about SeExpr’s language.

1 Like

ok, some other notes:

Right now, the value of the color is pushed into a qcolor which is then converted to a kocolor to be put onto the canvas. Sometimes this can lead to errors where a value higher than 1.0 is put into qcolor, leading to krita seemingly freezing up because qt’s complaining and logging all those errors for each offending pixel. I end up having to use $color = min(abs($c), 1.0); when I am experimenting.

My suggestion is to…

  • Check if the image is RGB.
  • If so, check if it’s floating point.
  • if it is floating point, don’t normalize the value and use a qvector with from normalized channels value to turn the three values in order R, G, B into a kocolor directly.
  • if it is not floating point, truncate the values to fit within 0-1.0, then use qvector with from normalized channels value to turn the three values in order B, G, R into a kocolor directly.
  • If it is not rgb, truncate the values to fit within 0-1.0, then use the qcolor path.

This will allow people to have their procedural textures in the color space of the image, which could be quite powerful for people doing scene linear images.

A part of me feels that maybe for lab and xyz, you could just stick in the color values as well, but it’ll be a little hard with regards to the input color…

BTW, since this is basically a shader language, I want to point out a lot of stuff from also works in seexpr, so we could work towards getting some of that stuff implemented as ‘known quantities’ people can experiment with…

Quick question: how does one create a fill layer? I’ve browsed the documentation and it mentions fill layers, but not how to create one. Also tried the right-clock menu on a layer to try and change the type (via properties or layer style). Must be missing something really obvious…

In the layer docker, open the “add layer” drop down (which drops up on my version for some reason) and select Fill Layer.

1 Like

Thank you! I knew it would be something really obvious.

1 Like

To do this, I need a copy of a floating-point RGB KoColorSpace and use convertPixelsTo the painting device’s color space. (KoColorSpaceRegistry does not provide one AFAIK)
Barring the need to use an intermediate buffer, as SeExpr doesn’t render alpha values (therefore it’s always an incomplete pixel), another problem would be what conversion flags and rendering intent to use here.

Hey all!

I’m glad to announce the third alpha of this project. Releases are available here:

Integrity hashes:

d5aa5138650c58ac93e16e5eef9e74f81d7eb4d3fa733408cee25e791bb7a3e1  krita-4.3.1-alpha-0b32800-x86_64.appimage

In this release, I fixed the following issues:

  • SeExpr textures use the scRGB color space, which is not supported by Qt’s QColor until 5.12. This makes the conversion to Krita space unbearably slow (thanks @wolthera )
  • Refactored SeExpr error reporting to make messages Qt-translatable.
    • This adds KDE’s ECM to the list of (optional) dependencies of SeExpr.
  • Error reporting is now available, including highlighting! (thanks @wolthera too for noticing)
  • Configuration is saved and restored when changing between Fill layer types (bug 422885, thanks @boud )
  • Cleaned up SeExpr headers
    • They are now installed only if used in the UI library itself.
  • UI labels have extra spacing (thanks Wolthera van Hövell)

Another outstanding issue is SeExpr’s vulnerability to the current LC_NUMERIC
locale, due to its use of sscanf and atof. I am sad to announce I won’t be
able to change this; the library I wanted to use, scn is itself vulnerable to locale changes.

But the most important feature, and final contribution, are bundleable presets!

This enables SeExpr scripts to be bundled just like any other resource in Krita.
Below you can find a bundle containing all of the example scripts posted by @wolthera .


Integrity hash:

1e4a1bc6a9b8238cee96dfee9a50e7db903fe7b665758caf731d53c96597dc20  Krita_Artists'_SeExpr_examples.bundle

Please let me know what you think!


Hey all,

Due to an incorrect build process, all AppImages I submitted have a broken keyboard layout detection.

Please try the AppImage below:

Integrity hash:

c8f194f913b738ce5cd86f31239af4aa72936fc1381afaea8c7d3b8811a905e7  krita-4.3.1-alpha-0685ece-x86_64-v2.appimage

As a bonus, this includes !412: multithreaded Fill Layers! This should reduce render times of SeExpr (and Simplex Noise, cc @deevad) to near zero :smile:

cc @raghukamath

1 Like

Hi! I encountered some issues when playing with the appimage.

  • semi-transparency of the layer
    I cannot tell why and when it happens, first I thought I painted it myself to grey, but later I was just really enthusiastic with scripting so it had to be a cause inside the system itself.
  • “Add new variable” adds a variable at the end of the current line, even if it’s inside a comment or something like that. Maybe if the line is not empty, it should add a new line afterwards and then add the variable text?
  • “Render script to thumbnail” is not working, when I believe you already got it, maybe it broke? (Twice it rendered to black square, once into a blue square…).
  • If I save a new custom preset, close the dialog and reopen and change stuff, it will forget that it was that preset and I cannot overwrite it, I need to save a new one
  • Some little details about the interface:
    • Because of the layout or sizehints or whatever of the layout, sometimes the space for variable widgets is bigger than needed but I cannot resize the script area to make it bigger
    • I don’t see whole variable names, they are cut off, even if I make the dialog much wider
    • Size of the dialog is not remembered and I need to resize it every time (this script are is sooo small :frowning: maybe you could remove the thumbnail from here, and just leave those two buttons “Save” and “Overwrite”? And other presets actions can be seen in the script chooser in the other tab anyway).
    • There is obviously “Save … Brush” and “Overwrite Brush”
    • ctrl+S saves the kra file :wink: (it doesn’t bother me, but that’s something to keep in mind since it can bother someone else potentially?)
    • I would wish for the comment color to be a bit more different from other things in the scripting area… I know it’s a different color, but it still blends in to other things, mostly variables. Maybe it could be even configurable? (Probably doesn’t need to be though).
    • I wonder, wouldn’t be it too much if it asked “Are you sure? You have unsaved changes” on Cancel? but that can be seen as too intrusive…

For now it’s all, I will write if I encounter something else.

Overall I think it’s really nice. It gives a lot of power to the user.

1 Like

Ok, I think I know what’s wrong with the semi-transparency… I’m often pushing Backspace even when the script area isn’t in focus, which makes Krita catch it and paint everything with light grey since that was the color I had as a Background color.

Hey all!

This project has been merged!

You should be able to use SeExpr for fun and profit as soon as the next nightly.

The next objective is getting the docs in shape – see this merge request for more information; and, of course, we still need your help for a good batch of scripts to bundle with!

Thank you all for helping out!