NVIDIA Iray API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
mi::IShader_graph_class Class Referenceabstract

This interface represents a shader graph class, a formalized description of a set of adhoc shader graphs with common characteristics and behaviors. More...

Inheritance diagram for mi::IShader_graph_class:
Inheritance graph
[legend]

Public Member Functions

virtual Sint32  create_metasl_graph (const char *name, Uint8 privacy=0) const =0
  Creates a new instance of a shader graph. More...
 
virtual Sint32  create_shader_graph (const char *name, Uint8 privacy=0) const =0
  Creates a new instance of a shader graph. More...
 
virtual const
IAttribute_container
access_input_parameters () const =0
  Returns an attribute container for all input parameters. More...
 
virtual Sint32  add_node (const char *node_name, const char *class_name)=0
  Create a node within this shader graph class named node_name and of type class_name. More...
 
virtual Sint32  add_export (const char *node_name, const char *class_name)=0
  Create an exported node within this shader graph class named node_name and of type class_name. More...
 
virtual const IShader access_shader (const char *node_name) const =0
  Returns a const shader instance node or NULL if there exists no such shader instance node. More...
 
virtual IShader edit_shader (const char *node_name) const =0
  Returns a non-const shader instance node or NULL if there exists no such shader instance node. More...
 
virtual const IShader_graph access_shader_graph (const char *node_name) const =0
  Returns a const shader graph instance node or NULL if there exists no such shader graph instance node. More...
 
virtual IShader_graph edit_shader_graph (const char *node_name) const =0
  Returns a non-const shader graph instance node or NULL if there exists no such shader graph instance node. More...
 
virtual const char *  get_filename () const =0
  Returns the filename containing the shader graph class. More...
 

Additional Inherited Members

- Public Types inherited from mi::base::Interface_declare< 0x167536d2, 0x1815, 0x4496, 0x8a, 0xfb, 0x64, 0xec, 0x78, 0x28, 0x2a, 0xb3, IScene_element >
typedef Interface_declare< id1,
id2, id3, id4, id5, id6, id7,
id8, id9, id10, id11,
IScene_element
Self
  Own type. More...
 
typedef Uuid_t< id1, id2, id3,
id4, id5, id6, id7, id8, id9,
id10, id11 > 
IID
  Declares the interface ID (IID) of this interface. More...
 
- Static Public Member Functions inherited from mi::base::Interface_declare< 0x167536d2, 0x1815, 0x4496, 0x8a, 0xfb, 0x64, 0xec, 0x78, 0x28, 0x2a, 0xb3, IScene_element >
static bool  compare_iid (const Uuid &iid)
  Compares the interface ID iid against the interface ID of this interface and of its ancestors. More...
 

Detailed Description

This interface represents a shader graph class, a formalized description of a set of adhoc shader graphs with common characteristics and behaviors.

Note
MetaSL is deprecated. Support for MetaSL might be removed in future releases. Use MDL instead.

Introduction

An mi::IShader_graph_class is a subclass of an mi::IScene_element. Thus, it inherits all the behaviors of mi::IScene_element. However, it also adds much functionality similar to that of mi::ICompound_shader_class. In particular, an mi::IShader_graph_class allows you, through its API, to explicitly formalize a program, an adhoc shader graph much like the graph of shaders within an mi::ICompound_shader_class, then to subsequently instantiate instances of such shader graphs. (For more information on adhoc shader graphs refer to the mi::IShader documentation.)

The program an mi::IShader_graph_class corresponds to is built from various smaller programs by connecting the output of one of these programs to the input of another program. Each of these smaller programs corresponds to an mi::IShader or an mi::IShader_graph. So, roughly, a mi::IShader_graph_class can be thought of as a formalized, named adhoc shader graph.

Building an mi::IShader_graph_class

Building an mi::IShader_graph_class consists of four phases:

  1. Creating an mi::IShader_graph_class
  2. Collecting the smaller program segments
  3. Connecting the smaller program segments
  4. Storing the mi::IShader_graph_class

You first create an mi::IShader_graph_class using a call to mi::neuraylib::ITransaction::create(const char* type_name,Uint32 argc = 0, const base::IInterface* argv[] = 0). (Note, unlike most uses of this method, creation here requires you pass non-trivial values for argc and argv.)

You then collect together the small program segments you wish to use in the newly created mi::IShader_graph_class. This is done through calls to the methods add_node() and add_export(). Upon success, each such call adds a named program segment to the collection of program segments available to this newly created mi::IShader_graph_class.

Next you connect these small program segments together. This consists of indicating which program segments process the inputs of the mi::IShader_graph_class, which program segments process the outputs of this first set of program segments, which program segments process the outputs of this second set of program segments etc. until, eventually, the outputs of a final set of program segments are connected to the inputs of the "export" nodes, program segments added through calls to the method add_export().

Finally, you store the newly created mi::IShader_graph_class in the database under the name you wish to assign to the newly created shader graph class. This store ends the build process. In particular, after you store this newly created mi::IShader_graph_class in the database, you can no longer edit it. In contrast to other mi::IScene_element's, editing an mi::IShader_graph_class after it has been stored in the database is expressly forbidden.

Creating an mi::IShader_graph_class

Creation of an mi::IShader_graph_class is done through use of the method mi::neuraylib::ITransaction::create(const char* type_name,Uint32 argc = 0, const base::IInterface* argv[] = 0).

When calling this method to create an mi::IShader_graph_class, the first argument type_name is the string "Shader_graph_class". The second argument argc is 1, and the final argument is an array of one mi::IAttribute_container. The mi::IAttribute_container specifies the set of allowed input parameters for the new shader graph class as well as their default values.

So, for example, creation of an mi::IShader_graph_class will generally be of the form:

// Create Input IAttribute_container
transaction->create<mi::IAttribute_container>("Attribute_container"));
// Populate input_parameters with input parameters and default values
// Set up argc and argv
mi::Uint32 argc = 1;
const mi::base::IInterface* argv[1] = { input_parameters.get() };
// Create IShader_graph_class
transaction->create<mi::IShader_graph_class>(
"Shader_graph_class",argc,argv));

Collecting the Smaller Program Segments

Collecting together the small program segments you wish to use in the newly created mi::IShader_graph_class is done through calls to the methods add_node() and add_export(). Each successful call to the method add_node() or add_export() adds a new, named program segment to the collection of program segments available to this newly created mi::IShader_graph_class. Those added through a call to the method add_node() are internal to this mi::IShader_graph_class while those added through a call to add_export() are allowed to be accessed by external code, similar to the private/public distinction in C++.

Each successful call to add_node() or add_export() adds a named mi::IShader or mi::IShader_graph instance node to the newly created mi::IShader_graph_class. It is these instances that are the small programs out of which the larger mi::IShader_graph_class program is built. (As mentioned in the documentation of mi::IShader and mi::IShader_graph, an mi::IShader instance is a program and an mi::IShader_graph instance also is a program.)

So, for example, if through an import you have loaded an mi::IShader_class named "shader2", then you can add a small program segment named "surface" of type "shader2", an mi::IShader instance, to the newly created mi::IShader_graph_class as follows:

// Add an mi::IShader instance node named "surface" of type "shader2"
mi::Sint32 result = shader_graph_class->add_node("surface",
"shader2");

where shader_graph_class is the mi::IShader_graph_class created in the last code snippet.

If one wished to allow external code to access the small program segment named "surface" that is of type "shader2", then one would use add_export() to add the program segment as follows:

// Add an mi::IShader instance export node named "surface" of type "shader2"
mi::Sint32 result = shader_graph_class->add_export("surface",
"shader2");

In addition, you can add instances of predefined mi::IShader_class's. For example, there exists a predefined mi::IShader_class named "Bsdf_phong". So, you can add a small program segment named "volume" of type "Bsdf_phong" to the newly created mi::IShader_graph_class as follows:

// Add an mi::IShader instance node named "volume" of type "Bsdf_phong"
mi::Sint32 result = shader_graph_class->add_node("volume",
"Bsdf_phong");

where shader_graph_class is your mi::IShader_graph_class. Again, if you wanted this program segment to be accessed by external code, then you would have added it using add_export() as follows:

// Add an mi::IShader instance external node named "volume" of type "Bsdf_phong"
mi::Sint32 result = shader_graph_class->add_export("volume",
"Bsdf_phong");

Also, you can add mi::IShader_graph instances. Assume that you defined an mi::IShader_graph_class "TestShaderGraphClass". You can then add a small program segment named "displacement" of type "TestShaderGraphClass", an mi::IShader_graph instance, to the newly created mi::IShader_graph_class as follows:

// Add an mi::IShader_graph instance node named "displacement" of type "TestShaderGraphClass"
mi::Sint32 result = shader_graph_class->add_node("displacement",
"TestShaderGraphClass");

where shader_graph_class is your mi::IShader_graph_class. Again, the add_export() variant is also possible.

Connecting the Smaller Program Segments

There are two means of connecting the smaller program segments:

Connecting using mi::IShader_connections

mi::IShader_graph_class supports the mi::IShader_connections interface. It is through this interface that you can connect together the small program segments within an mi::IShader_graph_class.

For example, assume that you wanted to connect the output of one mi::IShader instance node to the input of a second mi::IShader instance node. Concretely, assume that you have an mi::IShader instance node named "node1" and an mi::IShader instance node named "node2" both within the same shader graph class. Furthermore, assume that "node1" has an output named "result" of type Color and "node2" has an input named "input" of type Color. You can then connect the "result" output of "node1" to the "input" input of "node2" as follows:

// Obtain IShader_connections interface of shader_graph_class
shader_graph_class->get_interface<mi::IShader_connections>());
// Connect the "result" output of "node1" to the "input" input of "node2"
mi::Sint32 result = shader_connections->add_connection("node2.input",
"node1.result");

where shader_graph_class is your mi::IShader_graph_class.

Similarly, in the same situation, if you only wished to connect the "r" component of "result" to the "r" component of "input", then you can do so as follows:

// Obtain IShader_connections interface of shader_graph_class
shader_graph_class->get_interface<mi::IShader_connections>());
// Connect the "result.r" output of "node1" to the "input.r" input of "node2"
mi::Sint32 result = shader_connections->add_connection("node2.input.r",
"node1.result.r");

again shader_graph_class is your mi::IShader_graph_class.

Connecting using mi::IShader's and mi::IShader_graph's

You can obtain a non-const mi::IShader node using edit_shader() and you can obtain non-const mi::IShader_graph node using edit_shader_graph(). Using the mi::IShader_connections interface of mi::IShader or mi::IShader_graph you can then connect together the small program segments within an mi::IShader_graph_class.

As in our previous example, assume that you wanted to connect the output of one mi::IShader instance node to the input of a second mi::IShader instance node. Concretely, assume that you have an mi::IShader instance node named "node1" and an mi::IShader instance node named "node2" both within the same shader graph class. Furthermore, assume that "node1" has an output named "result" of type Color and "node2" has an input named "input" of type Color. You can then connect the "result" output of "node1" to the "input" input of "node2" as follows:

// Edit the IShader "node2"
shader_graph_class->edit_shader("node2"));
// Obtain IShader_connections interface of shader
shader->get_interface<mi::IShader_connections>());
// Connect the "result" output of "node1" to the "input" input of "node2"
mi::Sint32 result = shader_connections->add_connection("input",
"node1.result");

where shader_graph_class is your mi::IShader_graph_class. You can also write a similar snippet using an mi::IShader_graph and edit_shader_graph().

Similarly, in the same situation, if you only wished to connect the "r" component of "result" to the "r" component of "input", then you can do so as follows:

// Edit the IShader "node2"
shader_graph_class->edit_shader("node2"));
// Obtain IShader_connections interface of shader
shader->get_interface<mi::IShader_connections>());
// Connect the "result.r" output of "node1" to the "input.r" input of "node2"
mi::Sint32 result = shader_connections->add_connection("input.r",
"node1.result.r");

again shader_graph_class is your mi::IShader_graph_class. You can also write a similar snippet using an mi::IShader_graph and edit_shader_graph().

As another example, assume you wanted to connect the input of the shader graph class to the input of an mi::IShader instance node. Concretely, assume that the shader graph class has an input named "sg_input" of type Color. Assume also that you have an mi::IShader instance node named "node1" with an input named "s_input" of type Color. You can then connect the "sg_input" input of the shader graph class to the "s_input" input of the "node1" as follows:

// Edit the IShader "node1"
shader_graph_class->edit_shader("node1"));
// Obtain IShader_connections interface of shader
shader->get_interface<mi::IShader_connections>());
// Connect the "sg_input" input of the shader graph class to the "s_input" input of "node1"
mi::Sint32 result = shader_connections->add_connection("s_input",
"sg_input");

where shader_graph_class is your mi::IShader_graph_class. You can write a similar snippet using an mi::IShader_graph and edit_shader_graph(). (Note, using the mi::IShader_connections interface of a shader or shader graph is the only way to source the input parameter of a shader graph class for a connection.)

Storing an mi::IShader_graph_class

When one is finished collecting and connecting the smaller program segments, the final phase of building an mi::IShader_graph_class is storing the shader graph class in the database. Storing the shader graph class makes it available to be used like any other mi::IShader_graph_class.

Storing an mi::IShader_graph_class is like storing any other mi::IScene_element in the database . You employ an mi::neuraylib::ITransaction as follows:

// Store the shader_graph_class in the database
mi::Sint32 result = transaction->store(shader_graph_class.get(),
"MyShaderGraphClass");

where shader_graph_class is an mi::IShader_graph_class. The name under which the shader graph class is stored is then the name of the shader graph class. (In the case above we have introduced a shader graph class with the name "MyShaderGraphClass".)

Note that, unlike other mi::IScene_element classes, after storing a shader graph class in the database, you can no longer edit it only access it. This constraint is imposed to keep the the class and its instances in sync. If it were not imposed, it would lead to many strange and undesirable behaviors that are best avoided.

Using an mi::IShader_graph_class

To use an mi::IShader_graph_class you access it from the database and then proceed to call the desired methods on the retrieved shader class class.

For example, if you, as above, have a shader graph class named "MyShaderGraphClass" and wish to create an mi::IShader_graph instance "MyShaderGraph" of the type "MyShaderGraphClass", then you would do so as follows:

// Access the IShader_graph_class from the DB
shader_graph_class(
transaction->access<mi::IShader_graph_class>(
"MyShaderGraphClass"));
// Create shader graph "MyShaderGraph" of type "MyShaderGraphClass"
mi::Sint32 result = shader_graph_class->create_shader_graph("MyShaderGraph");

Note, create_shader_graph() behaves in a similar manner to mi::IShader_class::create_shader() except it creates a shader graph. A similar statement is true for create_metasl_graph().

Member Function Documentation

virtual const IAttribute_container* mi::IShader_graph_class::access_input_parameters ( ) const
pure virtual

Returns an attribute container for all input parameters.

The attribute container can be used to inquire about names and types of the input parameters.

virtual const IShader* mi::IShader_graph_class::access_shader ( const char *  node_name) const
pure virtual

Returns a const shader instance node or NULL if there exists no such shader instance node.

Note, you can not use this method to obtain a const mi::IShader_graph node instance.

This const mi::IShader instance node is usually used to examine the connections and input parameters of the specified mi::IShader node instance.

Parameters
node_name The name of the mi::IShader node to obtain
Returns
The mi::IShader instance node or NULL if no such node exists
virtual const IShader_graph* mi::IShader_graph_class::access_shader_graph ( const char *  node_name) const
pure virtual

Returns a const shader graph instance node or NULL if there exists no such shader graph instance node.

Note, you can not use this method to obtain a const mi::IShader instance node.

This const mi::IShader_graph instance node is usually used to examine the connections and input parameters of the specified mi::IShader_graph node instance.

Parameters
node_name The name of the mi::IShader_graph node to obtain
Returns
The mi::IShader_graph instance node or NULL if no such node exists
virtual Sint32 mi::IShader_graph_class::add_export ( const char *  node_name,
const char *  class_name 
)
pure virtual

Create an exported node within this shader graph class named node_name and of type class_name.

The created node will have all input parameters present and set to their default values or 0 if there is no apropos default value.

The name node_name must not be the name of an existing input parameter or node. In addition, the name node_name must be a valid MetaSL identifier.

The type class_name must be the name of an existing mi::IShader_class or mi::IShader_graph_class.

Parameters
node_name The name of the new node.
class_name The type of the new node
Returns
  • 0: Success.
  • -1: Invalid parameters (NULL pointer).
  • -2: Invalid class name
  • -3: Internal error
virtual Sint32 mi::IShader_graph_class::add_node ( const char *  node_name,
const char *  class_name 
)
pure virtual

Create a node within this shader graph class named node_name and of type class_name.

The created node will have all input parameters present and set to their default values or 0 if there is no apropos default value.

The name node_name must not be the name of an existing input parameter or node. In addition, the name node_name must be a valid MetaSL identifier.

The type class_name must be the name of an existing mi::IShader_class or mi::IShader_graph_class.

Parameters
node_name The name of the new node.
class_name The type of the new node
Returns
  • 0: Success.
  • -1: Invalid parameters (NULL pointer).
  • -2: Invalid class name
  • -3: Internal error
virtual Sint32 mi::IShader_graph_class::create_metasl_graph ( const char *  name,
Uint8  privacy = 0 
) const
pure virtual

Creates a new instance of a shader graph.

The new instance of type mi::IShader_graph will be stored under the name name in the database. The new shader graph instance has all input parameters added as attributes. The value of an input parameter is either the default set in the shader graph class or it is set to 0.

Note that this method requires that the shader graph class has been retrieved from the database. The method fails if it is called on a newly created shader graph class that has not yet been stored in the database.

Parameters
name The name of the new shader graph instance.
privacy The privacy level of the new shader graph instance. The constant mi::neuraylib::ITransaction::LOCAL_SCOPE can be used to indicate the privacy level of the scope of the transaction that was used to obtain the shader graph class object.
Returns
See mi::neuraylib::ITransaction::store() for possible return values. In addition, the value -10 indicates that the instance was not retrieved from the DB. You need to store it in the DB and access it again before using this method.
virtual Sint32 mi::IShader_graph_class::create_shader_graph ( const char *  name,
Uint8  privacy = 0 
) const
pure virtual

Creates a new instance of a shader graph.

The new instance of type mi::IShader_graph will be stored under the name name in the database. The new shader graph instance has no input parameters added as attributes.

Note that this method requires that the shader graph class has been retrieved from the database. The method fails if it is called on a newly created shader graph class that has not yet been stored in the database.

Parameters
name The name of the new shader graph instance.
privacy The privacy level of the new shader graph instance. The constant mi::neuraylib::ITransaction::LOCAL_SCOPE can be used to indicate the privacy level of the scope of the transaction that was used to obtain the shader graph class object.
Returns
See mi::neuraylib::ITransaction::store() for possible return values. In addition, the value -10 indicates that the instance was not retrieved from the DB. You need to store it in the DB and access it again before using this method.
virtual IShader* mi::IShader_graph_class::edit_shader ( const char *  node_name) const
pure virtual

Returns a non-const shader instance node or NULL if there exists no such shader instance node.

Note, you can not use this method to obtain a non-const mi::IShader_graph node instance.

This non-const mi::IShader instance node is usually used to modify an mi::IShader input parameter, to connect this mi::IShader to another node, or to connect this mi::IShader to an input parameter of this mi::IShader_graph_class.

Parameters
node_name The name of the mi::IShader node to obtain
Returns
The mi::IShader instance node or NULL if no such node exists
virtual IShader_graph* mi::IShader_graph_class::edit_shader_graph ( const char *  node_name) const
pure virtual

Returns a non-const shader graph instance node or NULL if there exists no such shader graph instance node.

Note, you can not use this method to obtain a non-const mi::IShader instance node.

This non-const mi::IShader_graph instance node is usually used to modify an mi::IShader_graph input parameter, to connect this mi::IShader_graph to another node, or to connect this mi::IShader_graph to an input parameter of this mi::IShader_graph_class.

Parameters
node_name The name of the mi::IShader_graph node to obtain
Returns
The mi::IShader_graph instance node or NULL if no such node exists
virtual const char* mi::IShader_graph_class::get_filename ( ) const
pure virtual

Returns the filename containing the shader graph class.

Returns
The absolute filename of the shader graph class, or NULL if it was not loaded from a file.