Args Files for Shaders
======================

.. highlight:: xml

One of the major purposes of Args Files is to describe how shader parameters
are presented in Katana's UI. Many aspects of this presentation - such as
widget types, hints, conditional visibility and locking, and help text can be
customized from within Katana's user interface, with an option to make these
changes persistent by exporting an Args File. Further details, such as grouping
parameters into pages, can be defined by editing Args Files in a text editor.

Search Path
-----------

When loading a shader, Katana searches for a corresponding Args File in a
number of directories relative to the shader's directory:

* :file:`Args` relative to the shader directory
* :file:`../Args` relative to the shader directory
* :file:`Args` relative to any path in :envvar:`KATANA_RESOURCES`.

The Args File is expected to be named :samp:`{shaderName}.args`, where
*shaderName* may or may not correspond to the name of the shader file on disk.

Typed Connection Checking
-------------------------

The constituent nodes of a Network Material can specify which connections
between ports of shading nodes are valid based on simple string tags. Shaders
can declare a set of named tags that indicate what they require as inputs, and
what they provide as outputs.

In the UI, connections can only be made between input and output ports where
tags that are required by an input port are matched as tags provided by the
output port. If connections are detected where not all required input port tags
are provided by a connected output port, the Network Material is flagged as
erroneous.

Outputs
'''''''

A set of tags can be declared for any shader to represent what types of data an
output of the shader provides. Tags are specified in Args Files as simple
string values using a syntax as shown in the following example::

    <args format="1.0">
      <output name="out">
        <tags>
          <tag value="color"/>
          <tag value="color4"/>
          <tag value="diffuse"/>
        </tags>
      </output>
    </args>

For RenderMan co-shaders, tag values are typically the names of methods the
co-shader provides, that can be interrogated by another shader. For example, if
a shader provides a method called ``outColor``, this can be advertised by
declaring an output tag called ``outColor``. The ability to declare multiple
tags allows co-shaders to advertise any number of different methods they
provide.

For renderers such as Arnold where shader components provide strongly-typed
data, these tags can simply be the names of the data types they provide, such
as ``float``, ``vector`` or ``color``.

Tag values can also be used for higher-level constructs, such as declaring that
a shader provides all the outputs necessary for a layerShader.

Inputs
''''''

For each connectable parameter of a shader, tag values can be declared to
indicate the type of data that is required for a connection to be valid. The
user interface makes use of these declarations to allow the user to only make
valid connections based on this type information.

Boolean logic is available to make more advanced rules specifying which
connections are valid for any input parameter. The available operators are
``and``, ``or``, and ``not``, and parentheses can be used to group expressions.

Here's an example::

    <args format="1.0">
      <param name="diffStr">
        <tags>
          <tag value="(color and diffuse and color4) or test"/>
        </tags>
      </param>
    </args>


``and``
~~~~~~~

In the example below, the output of a shader connected to the parameter is
required to provide all of the tags ``color``, ``color4``, and ``diffuse``. If
any tag is omitted, the connection is not allowed.

.. code-block:: xml

    <param name="diffStr">
      <tags>
        <tag value="color and color4 and diffuse"/>
      </tags>
    </param>

``or``
~~~~~~

In the example below, the output of a shader connected to the parameter is
required to provide at least one of the tags ``color``, ``color4``, or
``diffuse``. If none of the tags are provided, the connection is not allowed.

.. code-block:: xml

    <param name="diffStr">
      <tags>
        <tag value="color or color4 or diffuse"/>
      </tags>
    </param>


``not``
~~~~~~~

The ``not`` operator allows you to specify exception rules. In the example
below, an output port can be connected to the input port representing the
shader parameter only if the output does not provide ``float``::


    <param name="diffStr">
      <tags>
        <tag value="not float"/>
      </tags>
    </param>

``()``
~~~~~~

Tag values can also contain parentheses to allow you to group expressions for
either readability or logic purposes. In the example below, any output port
that provides ``diffuse`` as well as at least one of ``color`` or ``color4``
can be connected to the input port representing the shader parameter::

    <param name="diffStr" >
      <tags>
        <tag value="diffuse and (color or color4)"/>
      </tags>
    </param>


Co-Shaders
----------

It is a RenderMan convention to specify co-shaders used in a shader interface
using parameters of type ``string`` or ``shader``. If specified using type
``shader``, Katana detects that this is a co-shader port automatically. If
specified using type ``string``, you must provide a hint in the args file::

    <param name="Kd_color_mycoshader" coshaderPort="True"/>

Co-Shader Pairing
'''''''''''''''''

Katana allows co-shaders to be represented as Network Materials. For user
convenience, there is a convention that allows pairs of parameters,
representing a value and a port for a co-shader, to be presented to the user to
look like a single connectable value in the UI.

RenderMan co-shader pairing is used by adding a co-shader port and specifying
the co-shader's name in the ``coshaderPair`` XML attribute of the parameter. In
an Args File, this is achieved as follows::

    <args format="1.0">
       <param name="Kd_color_mycoshader" coshaderPort="True"/>
       <param name="Kd_color" widget="color" coshaderPair="Kd_color_mycoshader"/>
    </args>