diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-06-25 12:21:55 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2012-06-25 12:21:55 +0400 |
commit | 44c82198d4852484493c2e33b3ca4ad67fd76fd8 (patch) | |
tree | 4bf2bc23d6034647e0006dfb0c0d2f25f0eb951c /source | |
parent | 15cb064e1b853a56fc676db1c2869db47657d91a (diff) |
Optimization of Keying Blur operation
Separate X and Y passes of blurring like it's done for flat
gaussian blur. This reduces computing difficulty from size^2
to 2*size without any visual changes in matte.
Diffstat (limited to 'source')
4 files changed, 67 insertions, 24 deletions
diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp index 13488cc520b..d81092f21d7 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp @@ -66,13 +66,21 @@ OutputSocket *KeyingNode::setupPreBlur(ExecutionSystem *graph, InputSocket *inpu addLink(graph, separateOperation->getOutputSocket(0), combineOperation->getInputSocket(channel)); } else { - KeyingBlurOperation *blurOperation = new KeyingBlurOperation(); + KeyingBlurOperation *blurXOperation = new KeyingBlurOperation(); + KeyingBlurOperation *blurYOperation = new KeyingBlurOperation(); - blurOperation->setSize(size); + blurXOperation->setSize(size); + blurXOperation->setAxis(KeyingBlurOperation::BLUR_AXIS_X); - addLink(graph, separateOperation->getOutputSocket(0), blurOperation->getInputSocket(0)); - addLink(graph, blurOperation->getOutputSocket(0), combineOperation->getInputSocket(channel)); - graph->addOperation(blurOperation); + blurYOperation->setSize(size); + blurYOperation->setAxis(KeyingBlurOperation::BLUR_AXIS_Y); + + addLink(graph, separateOperation->getOutputSocket(), blurXOperation->getInputSocket(0)); + addLink(graph, blurXOperation->getOutputSocket(), blurYOperation->getInputSocket(0)); + addLink(graph, blurYOperation->getOutputSocket(0), combineOperation->getInputSocket(channel)); + + graph->addOperation(blurXOperation); + graph->addOperation(blurYOperation); } } @@ -86,17 +94,24 @@ OutputSocket *KeyingNode::setupPreBlur(ExecutionSystem *graph, InputSocket *inpu return convertYCCToRGBOperation->getOutputSocket(0); } -OutputSocket *KeyingNode::setupPostBlur(ExecutionSystem *graph, OutputSocket *postBLurInput, int size) +OutputSocket *KeyingNode::setupPostBlur(ExecutionSystem *graph, OutputSocket *postBlurInput, int size) { - KeyingBlurOperation *blurOperation = new KeyingBlurOperation(); + KeyingBlurOperation *blurXOperation = new KeyingBlurOperation(); + KeyingBlurOperation *blurYOperation = new KeyingBlurOperation(); + + blurXOperation->setSize(size); + blurXOperation->setAxis(KeyingBlurOperation::BLUR_AXIS_X); - blurOperation->setSize(size); + blurYOperation->setSize(size); + blurYOperation->setAxis(KeyingBlurOperation::BLUR_AXIS_Y); - addLink(graph, postBLurInput, blurOperation->getInputSocket(0)); + addLink(graph, postBlurInput, blurXOperation->getInputSocket(0)); + addLink(graph, blurXOperation->getOutputSocket(), blurYOperation->getInputSocket(0)); - graph->addOperation(blurOperation); + graph->addOperation(blurXOperation); + graph->addOperation(blurYOperation); - return blurOperation->getOutputSocket(); + return blurYOperation->getOutputSocket(); } OutputSocket *KeyingNode::setupDilateErode(ExecutionSystem *graph, OutputSocket *dilateErodeInput, int distance) diff --git a/source/blender/compositor/nodes/COM_KeyingNode.h b/source/blender/compositor/nodes/COM_KeyingNode.h index cc1d447c66e..17436a32353 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.h +++ b/source/blender/compositor/nodes/COM_KeyingNode.h @@ -30,7 +30,7 @@ class KeyingNode : public Node { protected: OutputSocket *setupPreBlur(ExecutionSystem *graph, InputSocket *inputImage, int size, OutputSocket **originalImage); - OutputSocket *setupPostBlur(ExecutionSystem *graph, OutputSocket *postBLurInput, int size); + OutputSocket *setupPostBlur(ExecutionSystem *graph, OutputSocket *postBlurInput, int size); OutputSocket *setupDilateErode(ExecutionSystem *graph, OutputSocket *dilateErodeInput, int distance); OutputSocket *setupDespill(ExecutionSystem *graph, OutputSocket *despillInput, OutputSocket *inputSrceen, float factor); OutputSocket *setupClip(ExecutionSystem *graph, OutputSocket *clipInput, int kernelRadius, float kernelTolerance, diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp b/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp index fd80b6b5ccf..eb956403e1f 100644 --- a/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp @@ -33,7 +33,8 @@ KeyingBlurOperation::KeyingBlurOperation() : NodeOperation() this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); - this->size = 0.0f; + this->size = 0; + this->axis = 0; this->setComplex(true); } @@ -53,16 +54,28 @@ void KeyingBlurOperation::executePixel(float *color, int x, int y, MemoryBuffer int bufferWidth = inputBuffer->getWidth(); int bufferHeight = inputBuffer->getHeight(); - int i, j, count = 0; + int i, count = 0; float average = 0.0f; - for (i = -this->size + 1; i < this->size; i++) { - for (j = -this->size + 1; j < this->size; j++) { - int cx = x + j, cy = y + i; + if (this->axis == 0) { + for (i = -this->size + 1; i < this->size; i++) { + int cx = x + i; - if (cx >= 0 && cx < bufferWidth && cy >= 0 && cy < bufferHeight) { - int bufferIndex = (cy * bufferWidth + cx) * 4; + if (cx >= 0 && cx < bufferWidth) { + int bufferIndex = (y * bufferWidth + cx) * 4; + + average += buffer[bufferIndex]; + count++; + } + } + } + else { + for (i = -this->size + 1; i < this->size; i++) { + int cy = y + i; + + if (cy >= 0 && cy < bufferHeight) { + int bufferIndex = (cy * bufferWidth + x) * 4; average += buffer[bufferIndex]; count++; @@ -79,10 +92,18 @@ bool KeyingBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBuff { rcti newInput; - newInput.xmin = input->xmin - this->size; - newInput.ymin = input->ymin - this->size; - newInput.xmax = input->xmax + this->size; - newInput.ymax = input->ymax + this->size; + if (this->axis == 0) { + newInput.xmin = input->xmin - this->size; + newInput.ymin = input->ymin; + newInput.xmax = input->xmax + this->size; + newInput.ymax = input->ymax; + } + else { + newInput.xmin = input->xmin; + newInput.ymin = input->ymin - this->size; + newInput.xmax = input->xmax; + newInput.ymax = input->ymax + this->size; + } return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.h b/source/blender/compositor/operations/COM_KeyingBlurOperation.h index 2848f260cbd..41ccb465eab 100644 --- a/source/blender/compositor/operations/COM_KeyingBlurOperation.h +++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.h @@ -32,11 +32,18 @@ class KeyingBlurOperation : public NodeOperation { protected: int size; + int axis; public: + enum BlurAxis { + BLUR_AXIS_X = 0, + BLUR_AXIS_Y = 1 + }; + KeyingBlurOperation(); - void setSize(float value) {this->size = value;} + void setSize(int value) {this->size = value;} + void setAxis(int value) {this->axis = value;} void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); |