From 51efa8a1f53f230b72210289483dae66f01de51a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Thu, 13 Feb 2014 11:46:15 +0100 Subject: Fix T38529, Blur node size 0 doesn't work. The blur operations were clamping the filter size to 1, which prevents no-op blur nodes. Further any value < 1 would also be ignored and in many combinations the filter scale setting ("Size") would only work in integer steps. Now most blur settings will work with smooth Size value scaling as well, meaning you can choose a reasonably large filter size (e.g. 10) and then use the Size factor to scale the actual blur radius smoothly. Note that non-integer filter sizes also depend on the filter type selected in the Blur node, e.g. "Flat" filtering will still ignore smooth filter sizes. Gaussian filters work best for this purpose. --- .../operations/COM_GaussianYBlurOperation.cpp | 40 ++++++++++------------ 1 file changed, 18 insertions(+), 22 deletions(-) (limited to 'source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp') diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp index f58e3a2b4f2..583305a0fc4 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp @@ -31,7 +31,7 @@ extern "C" { GaussianYBlurOperation::GaussianYBlurOperation() : BlurBaseOperation(COM_DT_COLOR) { this->m_gausstab = NULL; - this->m_rad = 0; + this->m_filtersize = 0; } void *GaussianYBlurOperation::initializeTileData(rcti *rect) @@ -52,11 +52,10 @@ void GaussianYBlurOperation::initExecution() initMutex(); if (this->m_sizeavailable) { - float rad = this->m_size * this->m_data->sizey; - CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS); - - this->m_rad = rad; - this->m_gausstab = BlurBaseOperation::make_gausstab(rad); + float rad = max_ff(m_size * m_data->sizey, 0.0f); + m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS); + + this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize); } } @@ -64,11 +63,10 @@ void GaussianYBlurOperation::updateGauss() { if (this->m_gausstab == NULL) { updateSize(); - float rad = this->m_size * this->m_data->sizey; - CLAMP(rad, 1.0f, MAX_GAUSSTAB_RADIUS); - - this->m_rad = rad; - this->m_gausstab = BlurBaseOperation::make_gausstab(rad); + float rad = max_ff(m_size * m_data->sizey, 0.0f); + m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS); + + this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize); } } @@ -82,18 +80,16 @@ void GaussianYBlurOperation::executePixel(float output[4], int x, int y, void *d int bufferstartx = inputBuffer->getRect()->xmin; int bufferstarty = inputBuffer->getRect()->ymin; - int miny = y - this->m_rad; - int maxy = y + this->m_rad; - int minx = x; - miny = max(miny, inputBuffer->getRect()->ymin); - minx = max(minx, inputBuffer->getRect()->xmin); - maxy = min(maxy, inputBuffer->getRect()->ymax - 1); + rcti &rect = *inputBuffer->getRect(); + int xmin = max_ii(x, rect.xmin); + int ymin = max_ii(y - m_filtersize, rect.ymin); + int ymax = min_ii(y + m_filtersize + 1, rect.ymax); int index; int step = getStep(); - const int bufferIndexx = ((minx - bufferstartx) * 4); - for (int ny = miny; ny <= maxy; ny += step) { - index = (ny - y) + this->m_rad; + const int bufferIndexx = ((xmin - bufferstartx) * 4); + for (int ny = ymin; ny < ymax; ny += step) { + index = (ny - y) + this->m_filtersize; int bufferindex = bufferIndexx + ((ny - bufferstarty) * 4 * bufferwidth); const float multiplier = this->m_gausstab[index]; madd_v4_v4fl(color_accum, &buffer[bufferindex], multiplier); @@ -132,8 +128,8 @@ bool GaussianYBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadB if (this->m_sizeavailable && this->m_gausstab != NULL) { newInput.xmax = input->xmax; newInput.xmin = input->xmin; - newInput.ymax = input->ymax + this->m_rad + 1; - newInput.ymin = input->ymin - this->m_rad - 1; + newInput.ymax = input->ymax + this->m_filtersize + 1; + newInput.ymin = input->ymin - this->m_filtersize - 1; } else { newInput.xmax = this->getWidth(); -- cgit v1.2.3