Arbitrary Attributes

Katana provides the ability to export arbitrary attributes to renderers. This information takes on a renderer-specific form at render time, such as user data for Arnold and primvars for RenderMan.

In its simplest form, an arbitrary attribute can be defined through its scope and value, as shown in the following OpScript code snippet:

Interface.SetAttr("geometry.arbitrary.myFloat.scope", StringAttribute("primitive"))
Interface.SetAttr("geometry.arbitrary.myFloat.value", FloatAttribute(1.0))

In the following example, a single float is converted to a color3 data type:

Interface.SetAttr("geometry.arbitrary.myFloatToColor3.scope", StringAttribute("primitive"))
Interface.SetAttr("geometry.arbitrary.myFloatToColor3.value", FloatAttribute(0.1))
Interface.SetAttr("geometry.arbitrary.myFloatToColor3.outputType", StringAttribute("color3"))

In this example, two colors are defined and then converted to uniform color[2] when rendering with RenderMan:

Interface.SetAttr("geometry.arbitrary.myColorArray.scope", StringAttribute("primitive"))
Interface.SetAttr("geometry.arbitrary.myColorArray.value", FloatAttribute({0.1, 0.2, 0.3, 0.4, 0.5, 0.6}))
Interface.SetAttr("geometry.arbitrary.myColorArray.inputType", StringAttribute("color3"))
Interface.SetAttr("geometry.arbitrary.myColorArray.elementSize", IntAttribute(3))

A simple example with each face of a cube assigned an alternating texture using an indexed array:

Interface.SetAttr("geometry.arbitrary.myIndexedArray.scope", StringAttribute("face"))
Interface.SetAttr("geometry.arbitrary.myIndexedArray.indexedValue", StringAttribute({"textureA.tx", "textureB.tx"}))
Interface.SetAttr("geometry.arbitrary.myIndexedArray.index", IntAttribute({0, 1, 0, 1, 0, 1}))

Type

Attribute

Description

string

geometry.arbitrary.<group>.scope

The scope of the attribute. Valid values are:

primitive

Constant.

face

Uniform.

point

Varying.

vertex

Face varying.

Support for the different scope types depends on the renderer’s capabilities. Therefore, not all of these are supported in every renderer.

string

geometry.arbitrary.<group>.inputType

Types of values in value or indexedValue. It’s important to note that the specified inputType must match the footprint of the data as described.

Valid values are:

  • float

  • double

  • int

  • string

  • color3

  • color4

  • normal2

  • normal3

  • vector2

  • vector3

  • vector4

  • point2

  • point3

  • point4

  • matrix9

  • matrix16

Support for different input types depends on the renderer’s capabilities. Therefore, not all of these are supported in every renderer.

string

geometry.arbitrary.<group>.outputType

Output type for the arbitrary attribute can be specified, if the intended output type (and footprint) differs from the input type but can be reasonably converted. Examples of reasonable conversions include: float -> color3, color3 -> color4.

any

geometry.arbitrary.<group>.value

Attribute containing the value. The type is dependent on the type specified. The type of the value can be int, float, double, or string.

The value can also be specified as an indexed list using the index and indexedValue attributes (see below).

int

geometry.arbitrary.<group>.index

List of indices. If no index is present, the index is implicitly defined by the scope.

any

geometry.arbitrary.<group>.indexedValue

List of values. The types of values in the list can be int, float, double, or string.

int

geometry.arbitrary.<group>.elementSize

This optional attribute determines the array length of each scoped element. This is used by some renderers, for example, RenderMan maps this to the [n] portion of a RenderMan type declaration: uniform color[2].

int

geometry.arbitrary.<group>.isArray

This optional attribute informs the renderer plug-in that the arbitrary attribute should be declared as an array (when set to 1) or a scalar (when set to 0). When this attribute is not set, the renderer plug-in typically infers this information from the length of the arbitrary attribute value.