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
  • No labels