Multiple Nodes in a Library - Arnold Developer Guide
If you create several custom nodes, it can be useful to create a loader that will load all of them from the same library file. It is also possible to create a metadata file with all the metadata information from all the shaders.
Two Simple Shaders
The first thing you need are the shaders you want to include; here are two very basic ones. Each node is defined in its own source code file, and both export their methods using the AI_SHADER_NODE_EXPORT_METHODS macro.
shader1.cpp
#include <ai.h>
AI_SHADER_NODE_EXPORT_METHODS(Shader1Mtd);
enum MyShader1Params { p_color };
node_parameters
{
AiParameterRGB("color1", 0.0f, 0.0f, 0.0f);
}
node_initialize {}
node_update {}
node_finish {}
shader_evaluate
{
sg->out.RGB() = AiShaderEvalParamRGB(p_color);
}
shader2.cpp
#include <ai.h>
AI_SHADER_NODE_EXPORT_METHODS(Shader2Mtd);
enum MyShader2Params { p_color };
node_parameters
{
AiParameterRGB("color2", 1.0f, 1.0f, 1.0f);
}
node_initialize {}
node_update {}
node_finish {}
shader_evaluate
{
sg->out.RGB() = AiShaderEvalParamRGB(p_color);
}
The Loader
When Arnold loads the shared, it will call the node_loader entry point several times, each time increasing the index i, until one of the calls returns false . So for loading two shaders, node_loader should return true for values of i between 0 and 1 and set the corresponding shader data in node , and return false for all other values.
loader.cpp
#include <ai.h>
#include <cstring>
extern const AtNodeMethods* Shader1Mtd;
extern const AtNodeMethods* Shader2Mtd;
enum{
SHADER_1 = 0,
SHADER_2
};
node_loader
{
switch (i)
{
case SHADER_1:
node->methods = Shader1Mtd;
node->output_type = AI_TYPE_RGB;
node->name = "shader1";
node->node_type = AI_NODE_SHADER;
break;
case SHADER_2:
node->methods = Shader2Mtd;
node->output_type = AI_TYPE_RGB;
node->name = "shader2";
node->node_type = AI_NODE_SHADER;
break;
default:
return false;
}
strcpy(node->version, AI_VERSION);
return true;
}
Compiling
The commands to compile are similar to a single shader, just using more files.
Linux
export ARNOLD_PATH=/path/to/arnold
c++ shader1.cpp shader2.cpp loader.cpp -o simple_shaders.so -Wall -O2 -shared -fPIC -I$ARNOLD_PATH/include -L$ARNOLD_PATH/bin -lai
macOS
export ARNOLD_PATH=/path/to/arnold
c++ shader1.cpp shader2.cpp loader.cpp -o simple_shaders.dylib -Wall -O2 -shared -fPIC -I$ARNOLD_PATH/include -L$ARNOLD_PATH/bin -lai
Windows Visual Studio command prompt
set ARNOLD_PATH=c:/path/to/arnold
cl /LD shader1.cpp shader2.cpp loader.cpp /I %ARNOLD_PATH%/include %ARNOLD_PATH%/lib/ai.lib /link /out:simple_shaders.dll
When you run kick -nodes in the directory containing the shader library (or run kick -nodes with the -l flag).
> cd /shader/location
> kick -nodes
or
> kick -l /shader/location -nodes
You should see entries for shader1 and shader2 in the output list
built-in nodes sorted by name:
...
loading plugins from .
shader1 shader
shader2 shader
