
	Toonz Shader Fxs Manual

==========================================================

 1. Introduction


Toonz 7.1 allows users to write new Fxs using GLSL (the
OpenGL Shading Language).

Shader Fx interfaces are read once at Toonz's startup,
but the underlying fx algorithm can be modified in
real time to ease the fx creation process.


Users reading these notes for the first time may want to
refer to the official GLSL guide at:

  http://www.opengl.org/documentation/glsl/

Up-and-running examples of GLSL (fragment) shader programs
can be found at the GLSL sanbox gallery, from which some of
the provided examples are adapted from (requires a
WebGL-compatible web browser, such as Firefox or Google
Chrome):

  http://glsl.heroku.com/

Further examples can be found at the beautiful gallery at:

  https://www.shadertoy.com/

==========================================================

 2. Requirements


The most recent version of your graphics drivers, as well
as a fairly recent graphics card.

Specifically, graphics drivers must support OpenGL 2.1,
Transform Feedback and Pixel Buffers (either as a built-in
feature or through extensions).

==========================================================

 3. Limitations


Shader fxs are rendered on the GPU, meaning that they are
typically executed in a massively parallel fashion - ie fast.

However, since most systems only adopt one GPU, only one
Shader fx is allowed to be rendered at the same time.
This means that Shader Fxs do not take advantage of multiple
rendering threads in a Toonz rendering process like common
CPU-based fxs do.


Shader Fx are intended to apply a fragment shader on the
output surface for the fx. In other words, each output pixel
is processed separately using the supplied fragment shader
program.

This prevents the implementation of more complex output
patterns that span multiple pixels at the same time.

Furthermore, there is no way to specify intermediate buffer
objects to read or write data to - which is often a common
need when writing fxs.

==========================================================

 3. Implementing a Shader Fx


In order to implement a shader fx it's currently necessary
to either create or edit the following files:

  a. <Toonz Stuff Path>/config/current.txt

	This file hosts the associations between fxs and
	their parameters and the names displayed in the GUI
	(which are not locale-dependent).

  b. <Toonz Stuff Path>/profiles/layouts/fxs/fxs.lst

	The list of fxs as displayed in the right-click
	contextual menus like "Add Fx" or "Insert Fx"

  c. <Toonz Stuff Path>/profiles/layouts/fxs/<Your Shader Fx Name>.xml

	Parameters tabbing in the Fx Parameters Editor

  d. <Toonz Library Path>/shaders/<Your Shader Fx Name>.xml

	The Shader Fx interface.

  e. The actual shader program files


Please, observe that the paths and names outside brackets
are mandatory.

Apart from point (d) and (e) discussed separately, it is best
to locate existing entries and emulate their behavior.
You can typically find related entries by searching "Shader"
in each file.

==========================================================

 4. The Shader Interface File


The Shader Fx Interface file at (3.d) is an xml document that
defines the main properties of the fx.

Specifically:

  a. Shader program files to be compiled at run-time

  b. Input ports for the fx

  c. Parameters

  d. Restrictions to the class of world/output coordinates
     transforms handled by the fx

The file is read once when Toonz starts, so any modification
will not be recognized until Toonz is restarted.


The complete recognized file structure is as follows:


<MainProgram>                       // (4.a) The applied fragment shader
  <Name>
    SHADER_myShaderName             // Internal name of the fx (mandatory, a simple app-unique literal id)
  </Name>
  <ProgramFile>
    "programs/myShader.frag"        // The shader program file (3.e), relative to the
  </ProgramFile>                    // path of the interface file.
</MainProgram>

<InputPorts>                        // (4.b) - Only a *fixed* number of ports allowed
  <InputPort>                       // A first port
    "Source"                        // The displayed port name
  </InputPort>

  <InputPort>                       // Second port
    "Control"
  </InputPort>
  
  <PortsProgram>                    // (4.a) Vertex shader used to acquire the geometry of
    <Name>                          // input images. See (5.b).
      SHADER_myShader_ports         // The unique id for the vertex shader program (mandatory)
    </Name>
    <ProgramFile>
      "programs/myShader_ports.vert"
    </ProgramFile>
  </PortsProgram>
</InputPorts>

<BBoxProgram>                       // (4.a) Vertex shader used to calculate the fx's bbox.
  <Name>                            //  See (5.c).
    SHADER_myShader_bbox
  </Name>
  <ProgramFile>
    "programs/myShader_bbox.vert"
  </ProgramFile>
</BBoxProgram>

<HandledWorldTransforms>            // (4.d) Optional, see (5.a)
  isotropic                         // May be either 'any' (default) or 'isotropic'.
</HandledWorldTransforms>           // Isotropic transforms exclude shears and non-uniform scales.

<Parameters>                        // (4.c)
  <Parameter>

    float radius                    // Parameter declaration

    <Default>                       // Additional Parameter attributes (can be omitted)
      10                            // The parameter default
    </Default>
    <Range>
      0 20                          // The parameter range
    </Range>
    <Concept>
      length                        // The parameter concept type - or, how it is represented
    </Concept>                      // by the Toonz GUI
  </Parameter>

  <Parameter>

    float angle

    <Concept>
      angle_ui                      // Concepts of type <concept type>_ui are editable in
      <Name>                        // camera stand
        "My Angle"
      </Name>
    </Concept>
  </Parameter>
</Parameters>

<Concept>                           // Composite parameter concepts can be formed by 2 or
                                    // more parameters
  polar_ui

  <Name>
    "My Polar Coordinates"
  </Name>
  <Parameter>                       // List of involved parameters
    radius
  </Parameter>
  <Parameter>
    angle
  </Parameter>
</Concept>

----------------------------------------------------------

4.1. Parameter Declarations


Parameters are introduced by a declaration typically matching
the corresponding GLSL variable declaration.

The complete recognized list of supported parameter types is:

  bool, float, vec2, int, ivec2, rgb, rgba


The 'rgb' and 'rgba' types map to GLSL 'vec3' and 'vec4'
variables respectively, but are displayed with the appropriate
color editors by Toonz - plus, the range of their components
automatically maps from [0, 255] in Toonz and the Shader
Interface file to [0.0, 1.0] in the corresponding shader program
files.

----------------------------------------------------------

4.2. Parameter Concepts


Parameter 'concepts' are additional parameter properties that
regard the way Toonz represents a certain parameter type.

For example, a 'float' variable type may either indicate
an angle, the length of a segment, a percentage value,
and more.

Fx writers may want to explicitly specify a parameter concept
for the following reasons:

  a. Impose a measure to the parameter (e.g. degrees, inches, %)

  b. Make the parameter editable in camera-stand


The complete list of supported parameter concepts is the following:

  percent            - Displayed with the percentage '%' unit

  length             - Displayed in length units (inches, mm, cm, etc..)

  angle              - Displayed in angular units '�'

  point              - A vec2 displayed in length units

  radius_ui          - Like length, displaying a radius in camstand. May compose with a point (the center)

  width_ui           - Like length, displaying a vertical line width. May compose with the line's angle.

  angle_ui           - Like angle, displaying it in camstand

  point_ui           - Like point, in camstand

  xy_ui              - Composes two float types in a point

  vector_ui          - Composes two float types in an 'arrow'-like vector

  polar_ui           - Like vector_ui, from a length and an angle

  size_ui            - Displays a square indicating a size. May compose width and height in a rect.

  quad_ui            - Composes 4 points in a quadrilateral

  rect_ui            - Composes width, height, and the optional center point in a rect

==========================================================

 5. Shader program files


A shader program file is a simple text file containing the
actual algorithms of a shader fx.

In the current implementation of Toonz Shader Fxs, there are
3 possible shader program files that need to be specified:

  a. The main fragment shader program, responsible of
     executing the code that actually renders the fx

  b. An optional vertex shader program to calculate the 
     geometries of contents required from input ports

  c. An optional vertex shader program to calculate the
     bounding box of the fx output

----------------------------------------------------------

 5.a. The 'MainProgram' Fragment Shader


The main program is in practice a standard GLSL fragment
shader - however, Toonz will provide it a set of additional
uniform input variables that must be addressed to correctly
compute the desired output.


The complete list of additional variables always supplied
by Toonz is:

  uniform mat3    worldToOutput;
  uniform mat3    outputToWorld;

These matrix variables describe the affine transforms mapping
output coordinates to Toonz's world coordinates, and vice-versa.

They include an additional coordinate as an OpenGL version-portable
way to perform translations by natural multiplication - transforming
a point is then done like:

  vec2 worldPoint = (outputToWorld * vec3(outPoint, 1.0)).xy

Fx parameters are typically intended in world coordinates,
and should be adjusted through these transforms - for example,
a camstand-displayed radius value must be multiplied by the
'worldToOutput' scale factors in order to get the corresponding
value in output coordinates.

World/Output transforms may be restricted to a specific sub-class
of affine transforms by specifying so in the Shader Interface File.

Restricting to isotropic transforms may be useful to simplify
cases where angular values are taken into account, since this
transforms class preserves angles by allowing only uniform scales,
rotations and translations. Non-uniform scales and shears are
later applied by Toonz on the produced fx output if necessary.


In case input ports have been specified, we also have:

  uniform sampler2D inputImage[n];
  uniform mat3      outputToInput[n];
  uniform mat3      inputToOutput[n];

The sampler variables correspond to the input content to the
fx. The matrix variables are the reference transforms from
output to input variables, and vice-versa.


Additional uniform variables corresponding to fx parameters
will also be supplied by Toonz. For example, if a "float radius"
parameter was specified, a corresponding

  uniform float radius;

input variable will be provided to the program.


WARNING: Toonz requires that *output* colors must be 
         'premultiplied' - that is, common RGB components
         (in the range [0, 1]) must be stored multiplied
         by their alpha component.

----------------------------------------------------------

 5.b. The optional 'PortsProgram' Vertex Shader


The shader program (b) is required in case an fx specifies
input ports, AND it needs to calculate some input content
in a different region than the required output.
It can be neglected otherwise.

For example, a blur fx requires that input contents outside
the required output rectangle are 'blurred in' it.


The 'PortsProgram' vertex shader is a one-shot shader
run by Toonz on a single dummy vertex - which uses
OpenGL 3.0's "Transform Feedback" extension to return a
set of predefined 'varying' output variables


The complete set of variables supplied by Toonz and required
in output by the program is:

  uniform mat3    worldToOutput;
  uniform mat3    outputToWorld;
  uniform vec4    outputRect;

  varying vec4    inputRect[portsCount];
  varying vec4    worldToInput[portsCount];

The transforms are intended in the same way as (5.a).

The outputRect and inputRect[] variables store the
(left, bottom, right, top) rect components in output
and input coordinates respectively.

Parameter input variables are obviously also supplied.


WARNING: *All* the required output variables must be
	 declared AND filled with values.

         There is no recognized default for them, and the
         fx will (silently) fail to render if some are not
         assigned.

----------------------------------------------------------

 5.c. The optional 'BBoxProgram' Vertex Shader


Some fx may be able to restrict their opaque renderable
area inside a rect.

For example, blurring an image will 'blur out' the image
content by the specified blur radius. Beyond that, the fx
will render full transparent pixels. Thus, the bounding
box of the fx in this case will be calculated as the
input bounding box, enlarged by the blur radius.

The default output bounding box is assumed to be infinite;
if that is the case, the BBoxProgram can be omitted.


Fx writers may want to supply an explicit program to
calculate the bounding box of the fx, given its input
bounding boxes. This is be useful in Toonz's rendering
pipeline because the software is then allowed to
restrict memory allocation (and fxs calculations)
for the output image to said output bounding box, resulting
in less memory consumption and increased speed.


The complete set of variables supplied by Toonz and required
in output by the program is:

  uniform vec4 infiniteRect;
  uniform vec4 inputBBox[portsCount];

  varying vec4 outputBBox;

The infiniteRect variable should be used to identify both
input and output infinite bboxes.

