State:New|TargetRelease:No Target|icon_bug|icon_nuke|database:public|Resolution:Not A Bug|BugID:308283|
Problem summary
Blinkscript Rolling Kernel does not sample correctly in Y axis
Customer reported version
nuke.11.0v1
Steps to reproduce
1) Open Nuke
2) Create a Checkerboard and connect a Blinkscript node
3) Paste the following code into the Kernel Source and Press "recompile"
// First, we define a struct to hold the data we want to roll from one pixel to the next.
struct RollingData
{
RollingData()
: sum(0.0f)
{}
// This struct contains a single, floating-point variable.
float sum;
};
// This RollingBoxBlurKernel derives from ImageRollingKernel. The first template argument to ImageRollingKernel
// tells us that this kernel can be run component-wise, as the blurred value of each component does not
// depend on any of the other components. The second template argument to ImageRollingKernel is the data structure
// to be carried from one position to the next, in this case the RollingData we defined above.
kernel RollingBoxBlurKernel : ImageRollingKernel<eComponentWise, RollingData>
{
// The RollingBoxBlurKernel requires read access to a one-dimensional range from its input, src.
// Reads outside the src image will be clamped to the edge value, as is usual for a blur.
Image<eRead, eAccessRanged1D, eEdgeClamped> src;
// We also require write access to the output image, dst.
Image<eWrite> dst;
param:
// This box blur can be run horizontally or vertically. The RollingData will be carried along rows in the
// horizontal case, and down columns in the vertical case.
bool horizontal;
// The radius of this box blur can also be changed. For larger radii, this rolling version of a box blur
// can be faster than the naive version, in which all values inside the box are added up at every location.
int radius;
local:
// The inverse of the box's width is stored here and used to normalise the summed values to get the blurred result
// at each point.
float _filterWidthInv;
void define()
{
// The "horizontal" parameter is given a default of true.
defineParam(horizontal, "horizontal", true);
// The "radius" is given a default value of 10 pixels, which equates to a 21-pixel-wide box.
defineParam(radius, "radius", 10);
}
void init()
{
// An ImageRollingKernel has a run-up which is performed before the start of each roll across the image (i.e.
// along a row or down a column), in order to initialise the data. In this case, we need to accumulate values
// into our "sum" variable before the rolling can begin. The rolling run-up is exclusive at the upper end, so
// here the run-up will be performed at each position in the range [-radius - 1, radius - 1].
setRunupMin(-radius - 1);
setRunupMax(radius);
// Here, the inverse of the box's width is stored and will be used later to normalise the blurred values.
_filterWidthInv = 1.0f / (2 * radius + 1);
// An ImageRollingKernel can be rolled horizontally or vertically. This is defined by setting the "rolling
// axis for the kernel. Here, the axis to roll along will depend on the value of the "horizontal" parameter.
Axis axis = horizontal ? eX : eY;
setRollingAxis(axis);
// We also need to set up access to the input image, src. At each point, we need to be able to read from
// positions in the range [-radius - 1, radius] (this range is inclusive on both sides).
src.setRange(-radius - 1, radius);
// We also need to set the axis for the one-dimensional ranged access to src. This will be the same as the
// axis we are rolling along.
src.setAxis(axis);
}
// The "rollingRunup" function is called once at every position in the run-up region. For example, if we are
// rolling along a row from position 0, this run-up function will be called at every position in the range
// [-radius - 1, radius -1], before the "process" function is called for the first time at position 0.
void rollingRunup()
{
// This function defines what to do inside the run-up region. Here, we want to accumulate values into
// our "sum" variable inside the RollingData struct.
sum;
}
// After the run-up, the process function will be called at every position in the remainder of the roll
// in turn, e.g. this might be from the start of a row to the end in the horizontal case.
void process()
{
// At each position, we want to drop one value from the back of the box and add a new one on the front,
// thereby shifting the box along by one position. We drop the value at (radius - 1) and add the value
// at radius, so our "sum" variable now contains the sum of the values in the range [radius, radius].
sum += src(radius);
// Finally, we multiply the sum by our normalisation factor, _filterWidthInv, to get the blurred value
// for the current position, and write it to the output image.
dst() = sum;
}
};

We're sorry to hear that
Please tell us why