DepthBlurKernelΒΆ

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);
  }
};