[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-kimageshop
Subject:    [documentation/docs-krita-org/krita/4.3] /: GSoC 2020: Add Disney Animation's SeExpr as a new Fill L
From:       L. E. Segovia <null () kde ! org>
Date:       2020-08-07 14:38:06
Message-ID: 20200807143806.025BE1241463 () leptone ! kde ! org
[Download RAW message or body]

Git commit a71ad098ba1c33708d60365edf66fb8219674644 by L. E. Segovia.
Committed on 07/08/2020 at 14:37.
Pushed by lsegovia into branch 'krita/4.3'.

GSoC 2020: Add Disney Animation's SeExpr as a new Fill Layer type

This commit documents the SeExpr Fill Layer generator, as implemented in \
graphics/krita!380 and graphics/krita!411.

See !145

CCMAIL: kimageshop@kde.org
(cherry picked from commit 9bb62c8ea128d9c5a059438108a5c8492d10e3c6)

A  +-    --    images/layers/SeExpr-David-Revoy.jpg
A  +17   -0    images/seexpr/LICENSE.md
A  +-    --    images/seexpr/SeExpr_add_variable.png
A  +-    --    images/seexpr/SeExpr_add_variable_vector.png
A  +-    --    images/seexpr/SeExpr_editor.png
A  +-    --    images/seexpr/SeExpr_editor_preset_mgmt.png
A  +-    --    images/seexpr/SeExpr_editor_script_error.png
A  +-    --    images/seexpr/SeExpr_editor_widgets.png
A  +-    --    images/seexpr/SeExpr_first_render.png
A  +-    --    images/seexpr/SeExpr_overwrite_preset.png
A  +-    --    images/seexpr/SeExpr_prop_1.png
A  +-    --    images/seexpr/SeExpr_rename_preset.png
A  +-    --    images/seexpr/SeExpr_save.png
A  +-    --    images/seexpr/SeExpr_script.png
A  +-    --    images/seexpr/Se_voronoi_1.png
A  +-    --    images/seexpr/Se_voronoi_2.png
A  +-    --    images/seexpr/Se_voronoi_3.png
A  +-    --    images/seexpr/Se_voronoi_4.png
A  +-    --    images/seexpr/Se_voronoi_5.png
A  +67   -0    reference_manual/layers_and_masks/fill_layer_generators/seexpr.rst
 M  +1    -0    reference_manual/layers_and_masks/fill_layers.rst
A  +51   -0    reference_manual/resource_management/seexpr_scripts.rst
A  +706  -0    reference_manual/seexpr.rst
A  +255  -0    tutorials/seexpr.rst

https://invent.kde.org/documentation/docs-krita-org/commit/a71ad098ba1c33708d60365edf66fb8219674644


diff --git a/images/layers/SeExpr-David-Revoy.jpg \
b/images/layers/SeExpr-David-Revoy.jpg new file mode 100644
index 000000000..17dd7c4b4
Binary files /dev/null and b/images/layers/SeExpr-David-Revoy.jpg differ
diff --git a/images/seexpr/LICENSE.md b/images/seexpr/LICENSE.md
new file mode 100644
index 000000000..94ba4cf59
--- /dev/null
+++ b/images/seexpr/LICENSE.md
@@ -0,0 +1,17 @@
+The images Se_voronoi_*.png are under the following license:
+
+Copyright Disney Enterprises, Inc.  All rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License
+and the following modification to it: Section 6 Trademarks.
+deleted and replaced with:
+
+6. Trademarks. This License does not grant permission to use the
+trade names, trademarks, service marks, or product names of the
+Licensor and its affiliates, except as required for reproducing
+the content of the NOTICE file.
+
+You may obtain a copy of the License at
+http://www.apache.org/licenses/LICENSE-2.0
+
diff --git a/images/seexpr/SeExpr_add_variable.png \
b/images/seexpr/SeExpr_add_variable.png new file mode 100644
index 000000000..d611abebf
Binary files /dev/null and b/images/seexpr/SeExpr_add_variable.png differ
diff --git a/images/seexpr/SeExpr_add_variable_vector.png \
b/images/seexpr/SeExpr_add_variable_vector.png new file mode 100644
index 000000000..74a66571f
Binary files /dev/null and b/images/seexpr/SeExpr_add_variable_vector.png \
                differ
diff --git a/images/seexpr/SeExpr_editor.png \
b/images/seexpr/SeExpr_editor.png new file mode 100644
index 000000000..843c7b344
Binary files /dev/null and b/images/seexpr/SeExpr_editor.png differ
diff --git a/images/seexpr/SeExpr_editor_preset_mgmt.png \
b/images/seexpr/SeExpr_editor_preset_mgmt.png new file mode 100644
index 000000000..9d4146c98
Binary files /dev/null and b/images/seexpr/SeExpr_editor_preset_mgmt.png \
                differ
diff --git a/images/seexpr/SeExpr_editor_script_error.png \
b/images/seexpr/SeExpr_editor_script_error.png new file mode 100644
index 000000000..35316d3bc
Binary files /dev/null and b/images/seexpr/SeExpr_editor_script_error.png \
                differ
diff --git a/images/seexpr/SeExpr_editor_widgets.png \
b/images/seexpr/SeExpr_editor_widgets.png new file mode 100644
index 000000000..5b7d7e0e9
Binary files /dev/null and b/images/seexpr/SeExpr_editor_widgets.png differ
diff --git a/images/seexpr/SeExpr_first_render.png \
b/images/seexpr/SeExpr_first_render.png new file mode 100644
index 000000000..24bd59fdf
Binary files /dev/null and b/images/seexpr/SeExpr_first_render.png differ
diff --git a/images/seexpr/SeExpr_overwrite_preset.png \
b/images/seexpr/SeExpr_overwrite_preset.png new file mode 100644
index 000000000..0a6d18bdc
Binary files /dev/null and b/images/seexpr/SeExpr_overwrite_preset.png \
                differ
diff --git a/images/seexpr/SeExpr_prop_1.png \
b/images/seexpr/SeExpr_prop_1.png new file mode 100644
index 000000000..3a2017699
Binary files /dev/null and b/images/seexpr/SeExpr_prop_1.png differ
diff --git a/images/seexpr/SeExpr_rename_preset.png \
b/images/seexpr/SeExpr_rename_preset.png new file mode 100644
index 000000000..66c209597
Binary files /dev/null and b/images/seexpr/SeExpr_rename_preset.png differ
diff --git a/images/seexpr/SeExpr_save.png b/images/seexpr/SeExpr_save.png
new file mode 100644
index 000000000..359c3db1d
Binary files /dev/null and b/images/seexpr/SeExpr_save.png differ
diff --git a/images/seexpr/SeExpr_script.png \
b/images/seexpr/SeExpr_script.png new file mode 100644
index 000000000..a94db9bee
Binary files /dev/null and b/images/seexpr/SeExpr_script.png differ
diff --git a/images/seexpr/Se_voronoi_1.png \
b/images/seexpr/Se_voronoi_1.png new file mode 100644
index 000000000..270bf786b
Binary files /dev/null and b/images/seexpr/Se_voronoi_1.png differ
diff --git a/images/seexpr/Se_voronoi_2.png \
b/images/seexpr/Se_voronoi_2.png new file mode 100644
index 000000000..d937ddc01
Binary files /dev/null and b/images/seexpr/Se_voronoi_2.png differ
diff --git a/images/seexpr/Se_voronoi_3.png \
b/images/seexpr/Se_voronoi_3.png new file mode 100644
index 000000000..fc2623628
Binary files /dev/null and b/images/seexpr/Se_voronoi_3.png differ
diff --git a/images/seexpr/Se_voronoi_4.png \
b/images/seexpr/Se_voronoi_4.png new file mode 100644
index 000000000..72dc31aa6
Binary files /dev/null and b/images/seexpr/Se_voronoi_4.png differ
diff --git a/images/seexpr/Se_voronoi_5.png \
b/images/seexpr/Se_voronoi_5.png new file mode 100644
index 000000000..8025849a2
Binary files /dev/null and b/images/seexpr/Se_voronoi_5.png differ
diff --git a/reference_manual/layers_and_masks/fill_layer_generators/seexpr.rst \
b/reference_manual/layers_and_masks/fill_layer_generators/seexpr.rst new \
file mode 100644 index 000000000..64cd6bb89
--- /dev/null
+++ b/reference_manual/layers_and_masks/fill_layer_generators/seexpr.rst
@@ -0,0 +1,67 @@
+.. meta::
+   :description:
+        How to use SeExpr as a Fill Layer in Krita.
+
+.. metadata-placeholder
+
+   :authors: - L. E. Segovia <amy@amyspark.me>
+   :license: GNU free documentation license 1.3 or later.
+
+.. index:: SeExpr
+.. _seexpr_fill_layer:
+
+SeExpr
+------
+
+.. versionadded:: 4.3.1
+
+.. image:: /images/layers/SeExpr-David-Revoy.jpg
+
+Fills the layer with a pattern specified through Disney Animation's
+`SeExpr expression language <https://wdas.github.io/SeExpr>`_.
+
+.. seealso::
+    - :ref:`seexpr_tut_intro`
+    - :ref:`seexpr`
+    - :ref:`resource_seexpr_scripts`
+    - `"Procedural texture generator (example and wishes)" on Krita \
Artists <https://krita-artists.org/t/procedural-texture-generator-example-and-wishes/7638>`_
 +    - `Inigo Quilez's articles <https://iquilezles.org/www/index.htm>`_
+    - `The Book of Shaders <https://thebookofshaders.com/>`_
+
+SeExpr is an embeddable, arithmetic expression language that enables you \
to +write shader-like scripts. Through this language, Krita can add \
dynamically  +generated textures like lava (example above), force fields, \
wood, marble,  +etc. to your layers.
+
+As with Patterns, you can create your own and use those as well.
+For some examples, please check out the thread `"Procedural texture \
generator (example and wishes)" on Krita Artists \
<https://krita-artists.org/t/procedural-texture-generator-example-and-wishes/7638>`_.
 +You can download them as a bundle through `Amyspark's blog \
<https://www.amyspark.me/blog/posts/2020/07/03/third-alpha-release.html>`_. \
+ +Script
+    Select the desired preset out of any existing bundled presets.
+    This tab is identical to the Pattern preset selector.
+
+    .. image:: /images/seexpr/SeExpr_script.png
+
+Options
+    This tab allows you to edit the selected preset, and apply its script 
+    to the layer.
+
+    .. image:: /images/seexpr/SeExpr_editor.png
+
+    There are three sections. The first bar allows you to edit and save \
the selected preset: +
+    .. image:: /images/seexpr/SeExpr_editor_preset_mgmt.png
+
+    If your script is syntactically correct, the middle box lets you
+    adjust its variables through widgets.
+
+    .. image:: /images/seexpr/SeExpr_editor_widgets.png
+
+    The lower box contains the script text, and shows the detected syntax 
+    errors, if any.
+
+    .. image:: /images/seexpr/SeExpr_editor_script_error.png
+
+    You can adjust how much space the latter two boxes have through their
+    splitter.
diff --git a/reference_manual/layers_and_masks/fill_layers.rst \
b/reference_manual/layers_and_masks/fill_layers.rst index \
                2c474f91b..cbb08f8ca 100644
--- a/reference_manual/layers_and_masks/fill_layers.rst
+++ b/reference_manual/layers_and_masks/fill_layers.rst
@@ -7,6 +7,7 @@
    :authors: - Wolthera van Hövell tot Westerflier \
                <griffinvalley@gmail.com>
              - Scott Petrovic
              - Alan
+             - L. E. Segovia <amy@amyspark.me>
    :license: GNU free documentation license 1.3 or later.
 
 .. index:: Layers, Fill, Generator
diff --git a/reference_manual/resource_management/seexpr_scripts.rst \
b/reference_manual/resource_management/seexpr_scripts.rst new file mode \
100644 index 000000000..815be24a8
--- /dev/null
+++ b/reference_manual/resource_management/seexpr_scripts.rst
@@ -0,0 +1,51 @@
+.. meta::
+   :description:
+        Creating and managing SeExpr script presets in Krita.
+
+.. metadata-placeholder
+
+   :authors: - L. E. Segovia <amy@amyspark.me>
+   :license: GNU free documentation license 1.3 or later.
+
+.. index:: Resources, SeExor
+.. _resource_seexpr_scripts:
+
+SeExpr Scripts
+==============
+
+.. image:: /images/seexpr/SeExpr_editor.png
+   :align: center
+
+SeExpr scripts allow you to render dynamically generated textures.
+They are saved as .se files.
+They can be used as fill for generated layers.
+
+.. seealso::
+    - :ref:`seexpr_tut_intro`
+    - :ref:`seexpr`
+    - :ref:`seexpr_fill_layer`
+    - `"Procedural texture generator (example and wishes)" on Krita \
Artists <https://krita-artists.org/t/procedural-texture-generator-example-and-wishes/7638>`_
 +    - `Inigo Quilez's articles <https://iquilezles.org/www/index.htm>`_
+    - `The Book of Shaders <https://thebookofshaders.com/>`_
+
+Adding new scripts
+------------------
+
+Like with :ref:`resource_patterns`, there is a similar UI with which you
+can manage SeExpr presets.
+This panel is available by opening the Fill Layer dialog, and selecting
+:guilabel:`SeExpr`:
+
+.. image:: /images/seexpr/SeExpr_script.png
+    :align: center
+
+At the bottom of the tab, beneath the resource-filter input field, there \
are the :guilabel:`Import resource` and :guilabel:`Delete resource` \
buttons. Select the former to add presets to the list. +
+Similarly, removing presets can be done by pressing the :guilabel:`Delete \
resource` button. Krita will not delete the actual file then, but rather \
black list it, and thus not load it. +
+Temporary scripts
+-----------------
+
+Layers keep a copy of the textual script that was used to generate them.
+You can access it by going to the Options tab and copying the text.
+You can then paste it into a new SeExpr Fill Layer.
diff --git a/reference_manual/seexpr.rst b/reference_manual/seexpr.rst
new file mode 100644
index 000000000..f3bcd6477
--- /dev/null
+++ b/reference_manual/seexpr.rst
@@ -0,0 +1,706 @@
+.. meta::
+   :description:
+        SeExpr Quick Reference for Krita
+
+.. metadata-placeholder
+
+   :authors: - L. E. Segovia <amy@amyspark.me> (reStructuredText)
+             - Disney Enterprises, Inc. (for the original)
+   :license: GNU free documentation license 1.3 or later, Apache 2.0
+
+.. index:: Fill Layer, SeExpr
+
+.. _seexpr:
+
+======================
+SeExpr Quick Reference
+======================
+
+This page details all the available variables, functions, and operators in \
SeExpr. +It is a heavily edited version of the official `user documentation \
<https://wdas.github.io/SeExpr/doxygen/userdoc.html>`_, adapted for usage \
with Krita. +
+.. seealso::
+    - Source code at `KDE Invent \
<https://invent.kde.org/lsegovia/seexpr>`_ +    - Disney's SeExpr `API \
Documentation <http://wdas.github.io/SeExpr/doxygen/>`_ +
+.. seealso::
+    - :ref:`seexpr_tut_intro`
+    - :ref:`seexpr_fill_layer`
+    - :ref:`resource_seexpr_scripts`
+    - `"Procedural texture generator (example and wishes)" on Krita \
Artists <https://krita-artists.org/t/procedural-texture-generator-example-and-wishes/7638>`_
 +    - `Inigo Quilez's articles <https://iquilezles.org/www/index.htm>`_
+    - `The Book of Shaders <https://thebookofshaders.com/>`_
+
+.. contents::
+
+*********
+Variables
+*********
+
+External variables
+==================
+
+These variables are provided by host applications, in this case Krita.
+They are registered with SeExpr's autocomplete help, which can be
+accessed by :kbd:`Ctrl+Space`.
+
+.. glossary::
+
+    $u, $v
+        Pixel position in normalized coordinates.
+
+    $w, $h
+        Image's width and height in pixels.
+
+Local Variables
+===============
+
+Local variables can be defined at the start of the expression::
+
+    $a = noise($P);
+    $b = noise($a * 1);
+    pow($a, 0.5) + $b
+
+External variables can also be overridden by local assignment.  This can \
be useful to scale the noise frequency for instance:: +
+    $P = $P * 10; # increase noise frequency
+    fbm(vnoise($P) + $P/4)
+
+
+******************
+Control Structures
+******************
+
+SeExpr, unlike many languages, provides **no control structures** except
+a form of `if` statements, known as the *ternary operator*::
+
+    $u = $i < .5 ? 0.0 : 10.0
+
+*******************************************
+Operators (listed in decreasing precedence)
+*******************************************
+
+.. glossary::
+
+    [  a,  b,  c  ]
+        vector constructor
+
+    $P[ n ]
+        vector component access
+
+        .. hint:: ``n`` must be 0, 1, or 2, e.g.::
+
+            $P[0]
+
+    ^
+        exponentiation
+
+        .. note:: Same as the ``pow`` function.
+
+    !
+        logical NOT
+
+    ~
+        inversion
+        
+        .. hint::
+            ::
+
+                ~$A
+
+            gives the same result as::
+
+                1 - $A
+
+    *  /   %
+        multiply, divide, modulus
+
+        .. note:: ``%`` is the same as the ``fmod`` function.
+
+    +  -
+        add, subtract
+
+    <  >   <=   >=
+        comparison: less than, greater than, less or equal than, greater \
or equal than +
+        .. note:: Only uses the first component of a vector.
+
+    ==   !=
+        equality, inequality
+
+    &&
+        logical AND
+
+    ||
+        logical OR
+
+    ?  :
+        ternary ``if`` operator
+
+        .. hint:: Example::
+
+            $u < .5 ? 0 : 1
+
+    ->
+        apply - The function on the right of the arrow is applied to the \
expression on the left. +
+        .. hint:: Examples::
+
+            $Cs  ->  contrast(.7) -> clamp(0.2,  0.8)
+            $u  ->  hsi(20,  1.2,  1,  $Cs  ->  gamma(1.2))
+
+********************
+Assignment Operators
+********************
+
+Besides the basic assignment statement::
+
+    $foo = $bar
+
+you can also do operator assignments such as::
+
+    $foo += $bar;
+
+which is equivalent to::
+
+    $foo = $foo + $bar;
+
+Additionally, there are:
+
+- ``+=``
+- ``-=``
+- ``/=``
+- ``%=``
+- ``*=``
+- ``^=``
+
+********
+Comments
+********
+
+You can add comments to your script by using the ``#`` character.
+SeExpr will then skip the rest of the line for rendering purposes.
+However, they are not ignored; comments can still be used to declare
+the valid value range of integer, float, and vector variables.
+This enables you to manage them using widgets that will accept the
+specified range.
+
+.. hint::
+    ``$var0`` is an integer variable that ranges between 0 and 10 \
inclusive:: +
+        $var0 = 0; # 0, 10
+
+    ``$var1`` is a floating point variable with the same range::
+
+        $var1 = 0; # 0.000, 10.000
+
+    ``$var2`` is a vector variable::
+
+        $var2 = [0, 0, 0] # 0.000, 10.000
+
+    The latter is very helpful; SeExpr considers vectors with range ``[0, \
1]`` as colors:: +
+        # this is a dark red
+        $color = [0.5, 0, 0] # 0.000, 1.000
+
+    In all cases, if not specified, the associated widgets' range will go \
from 0 to 1. +
+For a multi-line expression, each line may have its own comment.
+
+*****************
+Logging Functions
+*****************
+
+.. glossary::
+
+    void **printf** ( string format, [param0, param1, ...] )
+        Prints a string to stdout that is formatted as given. Formatting
+        parameters possible are ``%f`` for float (takes first component of \
vector +        argument) or ``%v`` for vector.
+
+        .. hint::
+            For example, if you wrote::
+
+                printf("test %f %v",[1,2,3],[4,5,6]);
+
+            you would get::
+
+                test 1 [4,5,6]
+
+***************************************
+Color, Masking, and Remapping Functions
+***************************************
+
+.. glossary::
+
+    float **bias** ( float x, float b)
+        Variation of gamma where control parameter goes from ``0`` to \
``1`` with +        values ``> 0.5`` pulling the curve up and values ``< \
0.5`` pulling the curve +        down.   Defined as ``pow(x, \
log(b)/log(0.5))``. +
+    float **boxstep** ( float x, float a )
+    float **gaussstep** ( float x, float a, float b )
+    float **linearstep** ( float x, float a, float b )
+    float **smoothstep** ( float x, float a, float b )
+        The step functions are zero for ``x < a`` and one for ``x > b`` \
(or ``x > a`` in +        the case of boxstep).   Between ``a`` and ``b``, \
the value changes +        continuously between zero and one.   The \
``gausstep`` function uses the +        standard Gaussian "bell" curve \
which is based on an exponential +        curve.   The ``smoothstep`` \
function uses a cubic curve.   Intuitively, +        ``gausstep`` is has a \
sharper transition near one and a softer transition +        near zero \
whereas ``smoothstep`` is has a medium softness near both one +        and \
zero. +
+    float **clamp** ( float x, float lo, float hi )
+        Constrain ``x`` to range ``[lo, hi]``.
+
+    float **compress** ( float x, float lo, float hi )  
+        Compress the dynamic range from ``[0, 1]`` to ``[lo, hi]``.
+
+    float **contrast** ( float x, float c )
+        Adjust the contrast.   For ``c`` from ``0`` to ``0.5``, the \
contrast +        is decreased.   For ``c > 0.5``, the contrast is \
increased. +
+    float **expand** ( float x, float lo, float hi )
+        Expand the dynamic range from ``[lo, hi]`` to ``[0, 1]``.
+
+    float **fit** ( float x, float a1, float b1, float a2, float b2 )
+        Linear remapping of ``[a1..x..b1]`` to ``[a2..x..b2]``
+
+    float **gamma** ( float x, float g)
+        ``pow(x, 1/g)``
+
+    float **invert** ( float x )
+        Invert the value.   Defined as ``1 - x``.
+
+    color **hsi** ( color x, float h, float s, float i, float map=1 )
+        The ``hsi``  function shifts the hue by ``h`` (in degrees) and
+        scales thesaturation and intensity by ``s`` and ``i``
+        respectively.   A map may be
+        supplied which will control the shift - the full shift will happen
+        when the map is one and no shift will happen when the map is zero. \
 +        The shift will be scaled back for values between zero and one.
+
+    color **hsltorgb** ( color hsl )
+    color **rgbtohsl** ( color rgb )
+        RGB to HSL color space conversion.  
+        HSL is Hue, Saturation, Lightness (all in range ``[0, 1]``).
+        These functions have also been extended to support RGB and HSL \
values +        outside of the range ``[0, 1]`` in a reasonable way.   For \
any RGB or HSL +        value (except for negative values), the conversion \
is well-defined +        and reversible.
+
+    color **midhsi** ( color x, float h, float s, float i, float map, \
float falloff=1, int interp=0 ) +        The ``midhsi`` function is just \
like the ``hsi`` function except that the +        control map is centered \
around the mid point (value of ``0.5``) and can +        scale the shift in \
both directions.  At the mid point, no shift +        happens.   At *1.0*, \
the full shift happens, and at ``0.0``, the full +        inverse shift \
happens.   Additional ``falloff`` and ``interp`` controls are +        \
provided to adjust the map using the ``remap`` function.   The default +    \
``falloff`` and ``interp`` values result in no remapping. +
+    float **mix** ( float a, float b, float alpha )
+        Blend of a and b according to alpha.   Defined as
+        ``a*(1-alpha) +b*alpha``.
+
+    float **remap** ( float x, float source, float range, float falloff, \
int interp ) +        General remapping function.   When ``x`` is within `` \
± range`` of source, +        the result is one.   The result falls to zero \
beyond that range over +        ``falloff`` distance.   The falloff shape \
is controlled by ``interp``. +
+        .. note::
+            Numeric values or named constants may be used:
+
+            - int **linear** = 0
+            - int **smooth** = 1
+            - int **gaussian** = 2
+
+***************
+Noise Functions
+***************
+
+.. glossary::
+
+    float **cellnoise** ( vector v )
+    float **cellnoise1** ( float x )
+    float **cellnoise2** ( float x, float y )
+    float **cellnoise3** ( float x, float y, float z )
+    color **ccellnoise** ( vector v )
+        ``cellnoise`` generates a field of constant colored cubes based on \
the +        integer location.   This is the same as the `PRMan cellnoise \
function <https://renderman.pixar.com/resources/RenderMan_20/cellnoise.html>`_.
 +
+        .. note::
+            ``ccellnoise`` outputs color cellnoise.
+
+
+    float **fbm** ( vector v, int octaves  =  6, float lacunarity  =  2, \
float gain  =  0.5 ) +    color **cfbm** ( vector v, int octaves  =  6, \
float lacunarity  =  2, float gain  =  0.5 ) +    vector **vfbm** ( vector \
v, int octaves  =  6, float lacunarity  =  2, float gain  =  0.5 ) +    \
float **fbm4** ( vector v, float time, int octaves  =  6, float lacunarity  \
=  2, float gain  =  0.5 ) +    color **cfbm4** ( vector v, float time, int \
octaves  =  6, float lacunarity  =  2, float gain  =  0.5 ) +    vector \
**vfbm4** ( vector v, float time, int octaves  =  6, float lacunarity  =  \
2, float gain  =  0.5 ) +        ``fbm`` (Fractal Brownian Motion) is a \
multi-frequency noise function.   +        The base frequency is the same \
as the ``noise`` function.   The total +        number of frequencies is \
controlled by ``octaves``.   The ``lacunarity`` +        is the spacing \
between the frequencies - a value of 2 means each +        octave is twice \
the previous frequency.   The ``gain`` controls how much +        each \
frequency is scaled relative to the previous frequency. +
+        .. note::
+
+            ``cfbm`` and ``cfbm4`` outputs color noise.
+
+            ``vfbm`` and ``vfbm4`` outputs vector noise.
+
+    float **hash** ( float seed1, [float seed2, ...] )
+        Like ``rand``, but with no internal seeds.   Any number of seeds \
may be +        given and the result will be a random function based on all \
the +        seeds.
+
+    float **noise** ( vector v )
+    float **noise** ( float x, float y )
+    float **noise** ( float x, float y, float z )
+    float **noise** ( float x, float y, float z, float w )
+    color **cnoise** ( vector v)
+    color **cnoise4** ( vector v, float t)
+    float **pnoise** ( vector v, vector period )
+    float **snoise** ( vector v)
+    float **snoise4** ( vector v, float t)
+    vector **vnoise** (vector v )
+    vector **vnoise4** (vector v, float t )
+        ``noise`` is a random function that smoothly blends between \
samples at +        integer locations.   This is Ken Perlin's original \
noise function. +
+        .. note::
+
+            ``cnoise`` and ``cnoise4`` output color noise.
+
+            ``noise4`` outputs signed vector noise.
+
+            ``pnoise`` outputs periodic noise.
+
+            ``snoise`` and ``snoise4`` output signed noise with range \
``[-1, 1]``. +
+            ``vnoise`` outputs signed vector noise.
+
+    float **rand** ( [float min, float max], [float seed] )
+        Random number between ``[min, max]`` (or ``[0, 1]`` if \
unspecified). +        If a seed is supplied, it will be used in addition \
to the internal +        seeds and may be used to create multiple distinct \
generators. +
+    float **turbulence** ( vector v, int octaves  =  6, float lacunarity  \
=  2, float gain  =  0.5 ) +    color **cturbulence** ( vector v, int \
octaves  =  6, float lacunarity  =  2, float gain  =  0.5 ) +    vector \
**vturbulence** ( vector v, int octaves  =  6, float lacunarity  =  2, \
float gain  =  0.5 ) +        ``turbulence`` is a variant of ``fbm`` where \
the absolute value of each +        noise term is taken.   This gives a \
more billowy appearance. +
+    float **voronoi** ( vector v, int type  =  1, float jitter  =  0.5, \
float fbmScale  =  0, int fbmOctaves  =  4, float fbmLacunarity  =  2, \
float fbmGain  =  0.5) +    color **cvoronoi** ( vector v, int type  =  1, \
float jitter  =  0.5, float fbmScale  =  0, int fbmOctaves  =  4, float \
fbmLacunarity  =  2, float fbmGain  =  0.5) +    vector **pvoronoi** ( \
vector v, float jitter  =  0.5, float fbmScale  =  0, int fbmOctaves  =  4, \
float fbmLacunarity  =  2, float fbmGain  =  0.5) +        ``voronoi`` is a \
cellular noise pattern. It is a jittered variant of +        ``cellnoise``.
+        The type parameter describes different variants of the noise
+        function.   The ``jitter`` param controls how irregular the \
pattern is +        (0 is like ordinary cellnoise).   The ``fbm...`` params \
can be +        used to distort the noise field.   When ``fbmScale`` is \
zero (the +        default), there is no distortion.   The remaining params \
are the same +        as for the ``fbm`` function.
+
+        .. hint::
+
+            Voronoi types 1 through 5:
+
+            |image0|   |image1|   |image2|   |image3|   |image4|  
+
+        .. note::
+            ``cvoronoi`` returns a random color for each cell and
+            ``pvoronoi`` returns the point location of the center of the \
cell. +
+
+*******************
+Selection Functions
+*******************
+
+.. glossary ::
+
+    float **choose** ( float index, float choice1, float choice2, [...] )
+        Chooses one of the supplied choices based on the index (assumed to \
be +        in range ``[0, 1]``).
+
+    int **cycle** ( int index, int loRange, int hiRange )
+        Cycles through values between loRange and hiRange based on \
supplied +        index.   This is an offset ``mod`` function.   The result \
is computed as +        ``loRange + value % (hiRange-loRange+1)``.
+
+    int **pick** ( float index, int loRange, int hiRange, [ float weights, \
... ] ) +        Picks values randomly between loRange and hiRange based on \
supplied +        index (which is automatically hashed).   The values will \
be +        distributed according to the supplied weights.   Any weights \
not +        supplied are assumed to be 1.0.
+
+    float **wchoose** ( float index, float choice1, float weight1, float \
choice2, float weight2, [...] ) +        Chooses one of the supplied \
choices based on the index (assumed to be +        in range ``[0, 1]``). \
The values will be distributed according to +        the supplied weights.
+
+.. hint::
+
+    This example returns integer values between 1 and 10::
+
+        pick(value, 1, 10)
+
+    This example returns the values 1 and 2 twice and 2.5 times as often
+    respectively as compared to the other values (3-10)::
+
+        pick(value, 1, 10, 2, 2.5)
+
+    This example returns 10, 11, and 13 through 20 (12 is skipped due to \
zero weight):: +
+        pick(value, 10, 20, 1, 1, 0)
+
+
+********************************************
+General Mathematical Constants and Functions
+********************************************
+
+.. glossary::
+
+    float **PI**
+        ::
+
+            float PI = 3.14159...
+
+    float **E**
+        ::
+
+            float E = 2.71828...
+
+.. glossary ::
+
+    float **abs** ( float x)
+        Absolute value of ``x``.
+
+    float **cbrt** ( float x )
+        Cube root.
+
+    float **ceil** ( float x )
+        Next higher integer.
+
+    float **exp** ( float x )
+        ``E`` raised to the ``x`` power.
+
+    float **floor** ( float x )
+        Next lower integer.
+
+    float **fmod** ( float x, float y )
+        Remainder of ``x / y``.
+
+        .. note:: Also available as the ``%`` operator.
+
+    float **log** ( float x )
+        Natural logarithm.
+
+    float **log10** ( float x )
+        Base 10 logarithm.
+
+    float **max** ( float a, float b )
+        Greater of ``a`` and ``b``.
+
+    float **min** ( float a, float b )
+        Lesser of ``a`` and ``b``.
+
+    float **pow** ( float x, float y )
+        ``x`` to the ``y`` power.
+
+        .. note:: Also available as the ``^`` operator.
+
+    float **round** ( float x )
+        Nearest integer.
+
+    float **sqrt** ( float x )
+        Square root.
+
+    float **trunc** ( float x )
+        Nearest integer towards zero.
+
+**********************
+Trigonometry Functions
+**********************
+
+.. glossary::
+
+    float **acos** ( float x )
+        Arc cosine.
+
+    float **acosd** ( float x )
+        Arc cosine in degrees.
+
+    float **acosh** ( float x )
+        Hyperbolic arc cosine.
+
+    float **asin** ( float x )
+        Arc sine.
+
+    float **asind** ( float x )
+        Arc sine in degrees.
+
+    float **asinh** ( float x )
+        Hyperbolic arc sine.
+
+    float **atan** ( float x )
+        Arc tangent.
+
+    float **atand** ( float x )
+        Arc tangent in degrees.
+
+    float **atan2** ( float y, float x)
+        Arc tangent of ``y/x`` between ``-PI`` and ``PI``.
+
+    float **atan2d** ( float y, float x )
+        Arc tangent in degrees of ``y/x`` between ``-180 º`` and ``180 \
º``. +
+    float **atanh** ( float x )
+        Hyperbolic arc tangent.
+
+    float **cos** ( float x )
+        Cosine.
+
+    float **cosd** ( float x )
+        Cosine in degrees.
+
+    float **cosh** ( float x )
+        Hyperbolic cosine.
+
+    float **deg** ( float x )
+        Radians to degrees.
+
+    float **hypot** ( float x, float y )
+        Length of 2D vector ``[x, y]``.
+
+    float **rad** ( float x )
+        Degrees to radians.
+
+    float **sin** ( float x )
+        Sine.
+
+    float **sind** ( float x )
+        Sine in degrees.
+
+    float **sinh** ( float x )
+        Hyperbolic sine.
+
+    float **tan** ( float x )
+        Tangent.
+
+    float **tand** ( float x )
+        Tangent in degrees.
+
+    float **tanh** ( float x )
+        Hyperbolic tangent.
+
+****************
+Vector Functions
+****************
+
+.. glossary::
+
+    float angle ( vector a, vector b )
+        Angle between two vectors (in radians).
+
+    vector **cross** ( vector a, vector b )
+        Vector cross product.
+
+    float **dist** ( vector a, vector b )
+        Distance between two points.
+
+    float **dot** ( vector a, vector b)
+        Vector dot product.
+
+    float **length** ( vector v )
+        Length of vector.
+
+    vector **norm** ( vector v )
+        Vector scaled to unit length.
+
+    vector **ortho** ( vector a, vector b )
+        Vector orthographic to two vectors.
+
+    vector **rotate** ( vector v, vector axis, float angle )
+        Rotates ``v`` around axis by given ``angle`` (in radians).
+
+    vector **up** ( vector v, vector up )
+        Rotates ``v`` such that the Y axis points in the given ``up`` \
direction. +
+
+**************
+Vector Support
+**************
+
+*Vectors* (points, colors, or 3D vectors) may be intermixed with *scalars*
+(simple floating point values).   If a scalar is used in a vector context, \
it is +replicated into the three components, e.g. ``0.5`` becomes ``[0.5, \
0.5, 0.5]``.   +
+If a vector is used in a scalar context, only the first component is used.
+One of the benefits of this is that all the functions that are defined
+to work with scalars automatically extend to vectors.   For instance,
+``pick``, ``choose``, ``cycle``, ``spline``, etc., will work just fine
+with vectors.
+
+Arithmetic operators such as ``+``, ``*``, etc., and scalar functions are
+applied component-wise to vectors.   For example, applying the ``gamma``
+function to a map adjusts the gamma of all three color channels.
+
+***************
+Curve Functions
+***************
+
+Interpolation of parameter values to a set of control points is governed
+by the following functions.
+
+.. glossary::
+
+    color **ccurve** ( float param, float pos0, color val0, int interp0, \
float pos1, color val1, int interp1, [...] ) +        Interpolates color \
ramp given by control points at ``param``. Control +        points are \
specified by triples of parameters ``pos_i``, ``val_i``, and +        \
``interp_i``. +        
+        .. hint::
+            Interpolation codes are:
+
+            - 0 - none
+            - 1 - linear
+            - 2 - smooth
+            - 3 - spline
+            - 4 - monotone (non-oscillating) spline
+
+    float **curve** ( float param, float pos0, float val0, int interp0, \
float pos1, float val1, int interp1, [...] ) +        Interpolates a 1D \
ramp defined by control points at ``param``. Control +        points are \
specified by triples of parameters ``pos_i``, ``val_i``, and +        \
``interp_i``. +        
+        .. hint::
+            Interpolation codes are:
+
+            - 0 - none
+            - 1 - linear
+            - 2 - smooth
+            - 3 - spline
+            - 4 - monotone (non-oscillating) spline
+
+    float **spline** ( float param, float y1, float y2, float y3, float \
y4, [...] ) +        Interpolates a set of values to the parameter \
specified where +        ``y1``, ..., ``yn`` are distributed evenly from \
``[0, 1]``. +
+**************
+Custom Plugins
+**************
+
+Custom functions may be written in C++ and loaded as one or more dynamic \
plugins.  See `Writing Custom Expression Plugins \
<https://wdas.github.io/SeExpr/doxygen/plugins.html>`_ for more details. +
+.. warning:: This functionality is not supported in Krita.
+
+.. |image0| image:: /images/seexpr/Se_voronoi_1.png
+.. |image1| image:: /images/seexpr/Se_voronoi_2.png
+.. |image2| image:: /images/seexpr/Se_voronoi_3.png
+.. |image3| image:: /images/seexpr/Se_voronoi_4.png
+.. |image4| image:: /images/seexpr/Se_voronoi_5.png
diff --git a/tutorials/seexpr.rst b/tutorials/seexpr.rst
new file mode 100644
index 000000000..acd7e951e
--- /dev/null
+++ b/tutorials/seexpr.rst
@@ -0,0 +1,255 @@
+.. meta::
+   :description lang=en:
+        Introduction to SeExpr
+
+.. metadata-placeholder
+   :authors: - L. E. Segovia <amy@amyspark.me>
+   :license: GNU free documentation license 1.3 or later.
+
+.. _seexpr_tut_intro:
+
+Introduction to SeExpr
+======================
+
+.. versionadded:: 4.3.1
+
+   This document will introduce you to the SeExpr expression language.
+
+****************
+What is SeExpr?
+****************
+
+SeExpr is an embeddable expression language, designed by Disney Animation,
+that allows host applications to render dynamically generated content.
+Pixar calls it `in its documentation \
<https://renderman.pixar.com/resources/RenderMan_20/PxrSeExpr.html>`_ a \
"scriptable pattern generator and +combiner".
+
+SeExpr is available within Krita as a Fill Layer.
+
+.. seealso::
+    - :ref:`seexpr`
+    - :ref:`seexpr_fill_layer`
+    - :ref:`resource_seexpr_scripts`
+    - `"Procedural texture generator (example and wishes)" on Krita \
Artists <https://krita-artists.org/t/procedural-texture-generator-example-and-wishes/7638>`_
 +    - `Inigo Quilez's articles <https://iquilezles.org/www/index.htm>`_
+    - `The Book of Shaders <https://thebookofshaders.com/>`_
+
+**********
+Background
+**********
+
+To understand what SeExpr is about, we need to differentiate between two \
types +of graphics, *raster* and *procedural*.
+
+The vast majority of the computer-generated stuff you see every day belong \
to +the first type-- images like photos, your favourite anime screenshots, \
memes, +are all a multitude of tiny little dots of color, or *pixels*, \
arranged into a +grid.
+
+Raster graphics have two drawbacks. First, once you create them, their
+resolution is **fixed**. You cannot zoom in and magically get any more \
detail. +And if you need to change them, either you go back to the source \
and sample it +again (which is sometimes impossible), or edit it with a \
raster graphics +program, like Krita.
+
+One of the biggest problems, however, is that we are always limited by the
+**space** our programs can use; either secondary storage, like SD cards, \
or +RAM. Unless compressed, image memory needs are `quadratic in the size \
of the +image <https://blender.stackexchange.com/questions/112505/why-is-my-half-resolution-render-taking-a-quarter-of-the-time-of-the-full-one>`_.
 +For a quick example, the :ref:`create_new_document` dialog of Krita tells
+you three bits of information: its size in pixels, the size of the pixel
+itself, and *the total memory needed*.
+
+.. image:: /images/Krita_newfile.png
+
+Here's a summary for square textures. Note that the memory needed
+is for *one layer only*:
+
+===== ==============
+Size  Memory needed
+===== ==============
+256   256 KB
+512   1 MB
+1024  4 MB
+2048  16 MB
+4096  64 MB
+===== ==============
+
+An alternative is to use :ref:`vector_graphics`. Vector graphics, for \
instance  +SVGs, employ mathematic formulae like splines and Bézier curves \
to describe a +shape. As they are mathematically defined, they can be \
resized to suit your  +needs without losing resolution.
+
+SeExpr belongs to a different class, *procedural graphics*. Similarly to \
vector +graphics, procedural graphics only need a few KBs of secondary \
storage for +their definition. But they are not defined by mathematical \
formulae; you +actually *code* how the color is calculated at each point of \
the texture. +And, because it is not limited in its precision, you can \
render complex +patterns in your layers at completely arbitrary resolution.
+
+****************
+Writing a script
+****************
+
+In this tutorial, we'll show you how to write a script in SeExpr, render \
it to +a layer, and then save it as a preset.
+
+We'll start by going to the :ref:`layer_docker`, and adding a new Fill \
Layer. +Then select the SeExpr generator from the list. You'll be greeted \
by this +window:
+
+   .. image:: /images/seexpr/SeExpr_editor.png
+
+The SeExpr generator dialog is divided in two tabs. For now, we'll stay on
+:guilabel:`Options`.
+
+.. note::
+   :ref:`fill_layers` describes these tabs in more detail.
+
+Let's start by painting a layer in light blue.
+
+First, SeExpr scripts must define an output variable, let's call it \
``$color``. +As SeExpr thinks of colors in the :ref:`RGB color \
space<model_rgb>`, +color variables are defined by a triplet of numbers \
known as a *vector*. +We'll start by defining the ``$color`` variable and \
giving it a value. +
+Go to the text box, and clear it if it has any text.
+Then, define and set ``$color`` to something like ``[0.5, 0.5, 1]``
+(half lit red, half lit green, fully lit blue)::
+
+   $color = [0.5, 0.5, 1];
+
+SeExpr needs to know which variable holds the final color value. This
+is done by writing at the end, on its own line, the name of the variable::
+
+   $color
+
+The script should now look like this::
+
+   $color = [0.5, 0.5, 1];
+   $color
+
+Click :guilabel:`OK`, and you'll render your first script!
+
+   .. image:: /images/seexpr/SeExpr_first_render.png
+
+.. warning::
+   To be absolutely precise, SeExpr **has no color management**.
+   It always renders textures as :ref:`32-bit float <bit_depth>`,
+   :ref:`gamma corrected <linear_and_gamma>`,
+   sRGB images. Krita transforms them to your document's color space
+   using the sRGB-elle-V2-srgbtrc.icc profile.
+
+   See :ref:`color_managed_workflow` for what this means.
+
+**********************************
+Managing your script using widgets
+**********************************
+
+There is also another way to define and edit your variables.
+Open the fill layer's properties by right clicking on :guilabel:`Fill \
Layer 1`, +and selecting :guilabel:`Layer Properties...`.
+
+.. image:: /images/seexpr/SeExpr_prop_1.png
+
+Notice the middle box? Once it detects a syntactically correct script,
+SeExpr enables a whole chunk of knobs to manage individual variables.
+In our example above, you can change ``$color``'s in three ways:
+
+- enter the red, green, or blue channel's value in the input fields
+- move the little colored sliders to change the respective channel
+- click on the preview square to the left of the boxes, to select a \
completely new color. +
+The last button on the middle box is always :guilabel:`Add new variable`.
+Click it and this dialog will open:
+
+.. image:: /images/seexpr/SeExpr_add_variable.png
+
+This dialog shows you all the types of variables that SeExpr accepts:
+
+.. glossary ::
+
+   Curve and Color curve
+      They are the SeExpr version of :ref:`Stop Gradients \
<resource_gradients>`: they interpolate a ramp given by a set of values. +
+      Curves represent 1D gradients, returning a single float at each \
evaluation point. +
+      Color curves represent RGB gradients, returning a Color at each \
point. +
+   Integers and Floats
+      Numbers.
+
+   Vector
+      A triplet of floats.
+
+   Color
+      A vector representing a RGB color.
+
+   Swatch
+      A list of Colors.
+
+   String
+      Usually single words.
+
+For instance, you could replicate ``$color`` in the :guilabel:`Vector` \
tab: +
+.. image:: /images/seexpr/SeExpr_add_variable_vector.png
+
+**************************
+Creating your first preset
+**************************
+
+Once your script is ready, you can reuse it by making a preset.
+
+You can create one through the top bar of the Options tab:
+
+   .. image:: /images/seexpr/SeExpr_editor.png
+
+Select :guilabel:`Save New SeExpr Preset...` and the following dialog will
+open:
+
+  .. image:: /images/seexpr/SeExpr_save.png
+
+You can edit the name of the preset in the top line edit box, and set a  \
thumbnail for easy identification. +
+.. hint :: The dialog will append "Copy" to the preset's name if it is a \
copy of an existing one. You can change it at will. +
+The dialog provides the following choices for setting a thumbnail:
+
+.. glossary::
+
+   Load Existing Thumbnail
+      If the preset already has a thumbnail (for instance, if you created \
it from an existing preset), this button will load and apply it. +
+   Load Image
+      Applies an image from the filesystem as a thumbnail.
+
+   Render Script to Thumbnail
+      Renders your script to a 256x256 texture, and applies the latter as \
a thumbnail. +
+   Clear Thumbnail
+      Deletes the thumbnail. Note that, if the preset is a copy of an \
existing one, this can be reverted by clicking :guilabel:`Load Existing \
Thumbnail`. +
+*************************
+Changing existing presets
+*************************
+
+If you change a preset's script, you will notice two new buttons in the \
top bar of the :guilabel:`Options` tab: +
+   .. image:: /images/seexpr/SeExpr_overwrite_preset.png
+
+The reload button will restore the preset to its original properties, \
while clicking on :guilabel:`Overwrite Preset` will save your changes. +
+Additionally, you can edit the preset's name by clicking on the rename \
button, +entering the new name, and clicking on :guilabel:`Save`:
+
+   .. image:: /images/seexpr/SeExpr_rename_preset.png
+
+
+*********************
+Bundling your presets
+*********************
+
+Sharing your scripts is easy! SeExpr script presets are just like any \
other +resource in Krita. Follow the instructions in \
:ref:`resource_management` to +create your own bundles.


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic