ID 308283 - Blinkscript Rolling Kernel does not sample correctly in Y axis

Follow

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


4) In the Kernel Parameters disable the horizontal knob and disable the GPU, the result has stepping in the result

5) Enable the horizontal knob and the stepping has gone

Below shows the expect result on the right, and the incorrect on the left:


Reproduced by support
This problem has been reproduced on:
Nuke 11.0v2 - Windows 10
Nuke 11.0v1 - Windows 10 - MacOSX 10.12 - CentOS 6.8
Nuke 10.5v5 - Windows 10
Nuke 10.5v1 - Windows 10
Nuke 10.0v6 - Windows 10
Nuke 10.0v1 - Windows 10
Nuke 9.0v9 - Windows 10
Nuke 9.0v1 - Windows 10
Nuke 8.0v7 - Windows 10
Nuke 8.0v1 - Windows 10

Earliest version tested
Nuke 8.0v1 as Blickscript was added in that version

Expected behaviour
For the result to be consistent between horizontal and vertical sampling

Actual behaviour
They are differnt

    We're sorry to hear that

    Please tell us why