The DepthBlurKernel applies a box blur of varying size to an input. The size of the blur is controlled by a depth channel read from a second input.
The user can change the Focal Point: the depth at which zero blur will be applied. The maximum Size of the blur can also be user-controlled.
//DepthBlurKernel: Applies a box blur to the first input, with the blur size at each pixel being determined by a "depth"
//value taken from the second input.
kernel DepthBlurKernel : ImageComputationKernel<ePixelWise>
{
Image<eRead, eAccessRanged2D, eEdgeClamped> src;
Image<eRead, eAccessRandom> depth;
Image<eWrite> dst; //the output image
param:
float2 focus;
int size;
//In define(), parameters can be given labels and default values.
void define() {
defineParam(size, "Size", 10);
defineParam(focus, "Focal Point", float2(100.0f, 100.0f));
}
//The init() function is run before any calls to process().
void init() {
src.setRange(-size, size);
}
//The process function is run at every pixel to produce the output.
void process(int2 pos) {
//Get the depth at the current pixel
const float depthHere = depth(pos.x, pos.y, 0);
//Get the depth at the focal point
const float depthAtFocus = bilinear(depth, focus[0], focus[1], 0);
//Find the difference in depth between the current pixel and the focal point
float z = fabs(depthHere - depthAtFocus);
//Use the depth difference to set the blur size for the current pixel.
const int blurSize = clamp((int)(z * size + 0.5f), 0, size);
//Accumulate src values in a window of blurSize x blurSize.
SampleType(src) sum = 0.0f;
for (int j = -blurSize; j <= blurSize; j++)
for (int i = -blurSize; i <= blurSize; i++) {
sum += src(i, j);
}
//Normalise the blurred value and set it into the dst image.
const int blurDiameter = 2 * blurSize + 1;
dst() = sum / (blurDiameter * blurDiameter);
}
};