Filter Nodes - Arnold Developer Guide
Example
This is an example filter node plugin, equivalent to the built-in gaussian_filter.

custom_gaussian_filter.cpp
#include <ai.h>
#include <string.h>
AI_FILTER_NODE_EXPORT_METHODS(CustomGaussianFilterMtd);
struct FilterData
{
float width;
};
node_parameters
{
AiParameterFlt("width", 2.0f);
}
node_initialize
{
AiFilterInitialize(node, false, NULL);
AiNodeSetLocalData(node, new FilterData());
}
node_update
{
FilterData* filter_data = (FilterData*)AiNodeGetLocalData(node);
filter_data->width = AiNodeGetFlt(node, AtString("width"));
AiFilterUpdate(node, filter_data->width);
}
node_finish
{
FilterData* filter_data = (FilterData*)AiNodeGetLocalData(node);
delete filter_data;
}
filter_output_type
{
switch (input_type)
{
case AI_TYPE_RGBA:
return AI_TYPE_RGBA;
default:
return AI_TYPE_NONE;
}
}
filter_pixel
{
FilterData* filter_data = (FilterData*)AiNodeGetLocalData(node);
const float width = filter_data->width;
float aweight = 0.0f;
AtRGBA avalue = AI_RGBA_ZERO;
while (AiAOVSampleIteratorGetNext(iterator))
{
// take into account adaptive sampling
float inv_density = AiAOVSampleIteratorGetInvDensity(iterator);
if (inv_density <= 0.f)
continue;
// determine distance to filter center
const AtVector2& offset = AiAOVSampleIteratorGetOffset(iterator);
const float r = AiSqr(2 / width) * (AiSqr(offset.x) + AiSqr(offset.y));
if (r > 1.0f)
continue;
// gaussian filter weight
const float weight = AiFastExp(2 * -r) * inv_density;
// accumulate weights and colors
avalue += weight * AiAOVSampleIteratorGetRGBA(iterator);
aweight += weight;
}
// compute final filtered color
if (aweight != 0.0f)
avalue /= aweight;
*((AtRGBA*)data_out) = avalue;
}
node_loader
{
if (i>0)
return false;
node->methods = CustomGaussianFilterMtd;
node->output_type = AI_TYPE_NONE;
node->name = "custom_gaussian_filter";
node->node_type = AI_NODE_FILTER;
strcpy(node->version, AI_VERSION);
return true;
}
Example Scene
The following .ass file generates an image similar to the one at the top of this page
custom_gaussian_filter.ass
options
{
AA_samples 1
outputs "RGBA RGBA filter testrender"
}
custom_gaussian_filter
{
name filter
width 16
}
driver_jpeg
{
name testrender
filename testrender.jpg
color_space sRGB
}
persp_camera
{
name mycamera
position 5 4 5
look_at 0 0 0
up 0 1 0
fov 50
}
utility
{
name myutil
color_mode n
shade_mode flat
}
sphere
{
name mysphere
center 0 0 0
radius 2
shader myutil
}
