Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/compositor/CMakeLists.txt2
-rw-r--r--source/blender/compositor/nodes/COM_KeyingNode.cpp35
-rw-r--r--source/blender/compositor/nodes/COM_KeyingNode.h1
-rw-r--r--source/blender/compositor/operations/COM_KeyingClipOperation.cpp95
-rw-r--r--source/blender/compositor/operations/COM_KeyingClipOperation.h50
-rw-r--r--source/blender/compositor/operations/COM_KeyingOperation.cpp56
-rw-r--r--source/blender/compositor/operations/COM_KeyingOperation.h5
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c2
8 files changed, 200 insertions, 46 deletions
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt
index c71168b2d2e..6fc938c192c 100644
--- a/source/blender/compositor/CMakeLists.txt
+++ b/source/blender/compositor/CMakeLists.txt
@@ -333,6 +333,8 @@ set(SRC
operations/COM_KeyingScreenOperation.h
operations/COM_KeyingDespillOperation.cpp
operations/COM_KeyingDespillOperation.h
+ operations/COM_KeyingClipOperation.cpp
+ operations/COM_KeyingClipOperation.h
operations/COM_ColorSpillOperation.cpp
operations/COM_ColorSpillOperation.h
diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp
index 9e29a99293e..2bc502a5f86 100644
--- a/source/blender/compositor/nodes/COM_KeyingNode.cpp
+++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp
@@ -27,12 +27,13 @@
#include "COM_KeyingOperation.h"
#include "COM_KeyingDespillOperation.h"
+#include "COM_KeyingClipOperation.h"
#include "COM_SeparateChannelOperation.h"
#include "COM_CombineChannelsOperation.h"
#include "COM_ConvertRGBToYCCOperation.h"
#include "COM_ConvertYCCToRGBOperation.h"
-#include "COM_FastGaussianBlurOperation.h"
+#include "COM_GaussianBokehBlurOperation.h"
#include "COM_SetValueOperation.h"
#include "COM_DilateErodeOperation.h"
@@ -72,8 +73,9 @@ OutputSocket *KeyingNode::setupPreBlur(ExecutionSystem *graph, InputSocket *inpu
setValueOperation->setValue(1.0f);
graph->addOperation(setValueOperation);
- FastGaussianBlurOperation *blurOperation = new FastGaussianBlurOperation();
+ GaussianBokehBlurOperation *blurOperation = new GaussianBokehBlurOperation();
blurOperation->setData(&preBlurData);
+ blurOperation->setQuality(COM_QUALITY_HIGH);
addLink(graph, separateOperation->getOutputSocket(0), blurOperation->getInputSocket(0));
addLink(graph, setValueOperation->getOutputSocket(0), blurOperation->getInputSocket(1));
@@ -104,8 +106,9 @@ OutputSocket *KeyingNode::setupPostBlur(ExecutionSystem *graph, OutputSocket *po
setValueOperation->setValue(1.0f);
graph->addOperation(setValueOperation);
- FastGaussianBlurOperation *blurOperation = new FastGaussianBlurOperation();
+ GaussianBokehBlurOperation *blurOperation = new GaussianBokehBlurOperation();
blurOperation->setData(&postBlurData);
+ blurOperation->setQuality(COM_QUALITY_HIGH);
addLink(graph, postBLurInput, blurOperation->getInputSocket(0));
addLink(graph, setValueOperation->getOutputSocket(0), blurOperation->getInputSocket(1));
@@ -149,6 +152,20 @@ OutputSocket *KeyingNode::setupDespill(ExecutionSystem *graph, OutputSocket *des
return despillOperation->getOutputSocket(0);
}
+OutputSocket *KeyingNode::setupClip(ExecutionSystem *graph, OutputSocket *clipInput, float clipBlack, float clipWhite)
+{
+ KeyingClipOperation *clipOperation = new KeyingClipOperation();
+
+ clipOperation->setClipBlack(clipBlack);
+ clipOperation->setClipWhite(clipWhite);
+
+ addLink(graph, clipInput, clipOperation->getInputSocket(0));
+
+ graph->addOperation(clipOperation);
+
+ return clipOperation->getOutputSocket(0);
+}
+
void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
{
InputSocket *inputImage = this->getInputSocket(0);
@@ -163,9 +180,6 @@ void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext *
/* keying operation */
KeyingOperation *keyingOperation = new KeyingOperation();
- keyingOperation->setClipBlack(keying_data->clip_black);
- keyingOperation->setClipWhite(keying_data->clip_white);
-
inputScreen->relinkConnections(keyingOperation->getInputSocket(1), 1, graph);
if (keying_data->blur_pre) {
@@ -180,11 +194,14 @@ void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext *
graph->addOperation(keyingOperation);
+ postprocessedMatte = keyingOperation->getOutputSocket();
+
+ if (keying_data->clip_black > 0.0f || keying_data->clip_white< 1.0f)
+ postprocessedMatte = setupClip(graph, postprocessedMatte, keying_data->clip_black, keying_data->clip_white);
+
/* apply blur on matte if needed */
if (keying_data->blur_post)
- postprocessedMatte = setupPostBlur(graph, keyingOperation->getOutputSocket(), keying_data->blur_post);
- else
- postprocessedMatte = keyingOperation->getOutputSocket();
+ postprocessedMatte = setupPostBlur(graph, postprocessedMatte, keying_data->blur_post);
/* matte dilate/erode */
if (keying_data->dilate_distance != 0) {
diff --git a/source/blender/compositor/nodes/COM_KeyingNode.h b/source/blender/compositor/nodes/COM_KeyingNode.h
index 894d0ddc095..9d4067ce599 100644
--- a/source/blender/compositor/nodes/COM_KeyingNode.h
+++ b/source/blender/compositor/nodes/COM_KeyingNode.h
@@ -37,6 +37,7 @@ protected:
OutputSocket *setupPostBlur(ExecutionSystem *graph, OutputSocket *postBLurInput, int size);
OutputSocket *setupDilateErode(ExecutionSystem *graph, OutputSocket *dilateErodeInput, int distance);
OutputSocket *setupDespill(ExecutionSystem *graph, OutputSocket *despillInput, InputSocket *inputSrceen, float factor);
+ OutputSocket *setupClip(ExecutionSystem *graph, OutputSocket *clipInput, float clipBlack, float clipWhite);
public:
KeyingNode(bNode *editorNode);
void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.cpp b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp
new file mode 100644
index 00000000000..559d282f613
--- /dev/null
+++ b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ * Sergey Sharybin
+ */
+
+#include "COM_KeyingClipOperation.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+
+KeyingClipOperation::KeyingClipOperation(): NodeOperation()
+{
+ this->addInputSocket(COM_DT_VALUE);
+ this->addOutputSocket(COM_DT_VALUE);
+
+ this->clipBlack = 0.0f;
+ this->clipWhite = 1.0f;
+
+ this->pixelReader = NULL;
+}
+
+void KeyingClipOperation::initExecution()
+{
+ this->pixelReader = this->getInputSocketReader(0);
+}
+
+void KeyingClipOperation::deinitExecution()
+{
+ this->pixelReader = NULL;
+}
+
+void KeyingClipOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
+{
+ const int delta = 3;
+
+ float pixelColor[4];
+ int width = this->getWidth(), height = this->getHeight();
+ int count_black = 0, count_white = 0;
+ int i, j;
+
+ this->pixelReader->read(pixelColor, x, y, sampler, inputBuffers);
+
+ for (i = -delta + 1; i < delta; i++) {
+ for (j = -delta + 1; j < delta; j++) {
+ int cx = x + j, cy = y + i;
+
+ if (i == 0 && j == 0)
+ continue;
+
+ if (cx >= 0 && cx < width && cy >= 0 && cy < height) {
+ float value[4];
+
+ this->pixelReader->read(value, cx, cy, sampler, inputBuffers);
+
+ if (value[0] < 0.4f)
+ count_black++;
+ else if (value[0] > 0.6f)
+ count_white++;
+ }
+ }
+ }
+
+ color[0] = pixelColor[0];
+
+ if (count_black >= 22 || count_white >= 22) {
+ if (count_black >= 4 || count_white >= 4) {
+ if (color[0] < this->clipBlack)
+ color[0] = 0.0f;
+ else if (color[0] >= this->clipWhite)
+ color[0] = 1.0f;
+ else
+ color[0] = (color[0] - this->clipBlack) / (this->clipWhite - this->clipBlack);
+ }
+ }
+}
diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.h b/source/blender/compositor/operations/COM_KeyingClipOperation.h
new file mode 100644
index 00000000000..1141e0b47ab
--- /dev/null
+++ b/source/blender/compositor/operations/COM_KeyingClipOperation.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Jeroen Bakker
+ * Monique Dewanchand
+ * Sergey Sharybin
+ */
+
+#ifndef _COM_KeyingClipOperation_h
+#define _COM_KeyingClipOperation_h
+
+#include "COM_NodeOperation.h"
+
+/**
+ * Class with implementation of black/white clipping for keying node
+ */
+class KeyingClipOperation : public NodeOperation {
+protected:
+ SocketReader *pixelReader;
+ float clipBlack;
+ float clipWhite;
+
+public:
+ KeyingClipOperation();
+
+ void initExecution();
+ void deinitExecution();
+
+ void setClipBlack(float value) {this->clipBlack = value;}
+ void setClipWhite(float value) {this->clipWhite = value;}
+
+ void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]);
+};
+
+#endif
diff --git a/source/blender/compositor/operations/COM_KeyingOperation.cpp b/source/blender/compositor/operations/COM_KeyingOperation.cpp
index 5f1c9d0640d..7d7ac378bed 100644
--- a/source/blender/compositor/operations/COM_KeyingOperation.cpp
+++ b/source/blender/compositor/operations/COM_KeyingOperation.cpp
@@ -28,26 +28,33 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
-static int get_pixel_primary_channel(float *pixel)
+static int get_pixel_primary_channel(float pixelColor[4])
{
- float max_value = MAX3(pixel[0], pixel[1], pixel[2]);
+ float max_value = MAX3(pixelColor[0], pixelColor[1], pixelColor[2]);
- if (max_value == pixel[0])
+ if (max_value == pixelColor[0])
return 0;
- else if (max_value == pixel[1])
+ else if (max_value == pixelColor[1])
return 1;
return 2;
}
-static float get_pixel_saturation(float *pixel, float screen_balance)
+static float get_pixel_saturation(float pixelColor[4], float screen_balance, int primary_channel)
{
- float min = MIN3(pixel[0], pixel[1], pixel[2]);
- float max = MAX3(pixel[0], pixel[1], pixel[2]);
- float mid = pixel[0] + pixel[1] + pixel[2] - min - max;
- float val = (1.0f - screen_balance) * min + screen_balance * mid;
+ int other_1 = (primary_channel + 1) % 3;
+ int other_2 = (primary_channel + 2) % 3;
- return (max - val) * (1.0f - val) * (1.0f - val);
+ float min = MIN2(pixelColor[other_1], pixelColor[other_2]);
+ float max = MAX2(pixelColor[other_1], pixelColor[other_2]);
+ float val = screen_balance * min + (1.0f - screen_balance) * max;
+
+ // original formula, also used by brecht
+ // works a bit crappy in areas with values > 1.0
+ // return (pixelColor[primary_channel] - val) * fabsf(1.0f - val);
+
+ // sergey's test formula
+ return pixelColor[1] - (pixelColor[0] + pixelColor[1]) * 0.5f;
}
KeyingOperation::KeyingOperation(): NodeOperation()
@@ -57,8 +64,6 @@ KeyingOperation::KeyingOperation(): NodeOperation()
this->addOutputSocket(COM_DT_VALUE);
this->screenBalance = 0.5f;
- this->clipBlack = 0.0f;
- this->clipWhite = 1.0f;
this->pixelReader = NULL;
this->screenReader = NULL;
@@ -84,31 +89,20 @@ void KeyingOperation::executePixel(float *color, float x, float y, PixelSampler
this->pixelReader->read(pixelColor, x, y, sampler, inputBuffers);
this->screenReader->read(screenColor, x, y, sampler, inputBuffers);
- float saturation = get_pixel_saturation(pixelColor, this->screenBalance);
- float screen_saturation = get_pixel_saturation(screenColor, this->screenBalance);
- int primary_channel = get_pixel_primary_channel(pixelColor);
- int screen_primary_channel = get_pixel_primary_channel(screenColor);
+ int primary_channel = get_pixel_primary_channel(screenColor);
+
+ float saturation = get_pixel_saturation(pixelColor, this->screenBalance, primary_channel);
+ float screen_saturation = get_pixel_saturation(screenColor, this->screenBalance, primary_channel);
- if (primary_channel != screen_primary_channel) {
- /* different main channel means pixel is on foreground */
+ if (saturation < 0) {
color[0] = 1.0f;
}
- else if (saturation >= screen_saturation) {
- /* saturation of main channel is more than screen, definitely a background */
+ else if (saturation >= screen_saturation) {
color[0] = 0.0f;
}
else {
- float distance;
-
- distance = 1.0f - saturation / screen_saturation;
-
- color[0] = distance * distance;
+ float distance = 1.0f - saturation / screen_saturation;
- if (color[0] < this->clipBlack)
- color[0] = 0.0f;
- else if (color[0] >= this->clipWhite)
- color[0] = 1.0f;
- else
- color[0] = (color[0] - this->clipBlack) / (this->clipWhite - this->clipBlack);
+ color[0] = distance;
}
}
diff --git a/source/blender/compositor/operations/COM_KeyingOperation.h b/source/blender/compositor/operations/COM_KeyingOperation.h
index 546ff355573..0ce6481b835 100644
--- a/source/blender/compositor/operations/COM_KeyingOperation.h
+++ b/source/blender/compositor/operations/COM_KeyingOperation.h
@@ -39,8 +39,6 @@ protected:
SocketReader *pixelReader;
SocketReader *screenReader;
float screenBalance;
- float clipBlack;
- float clipWhite;
public:
KeyingOperation();
@@ -48,9 +46,6 @@ public:
void initExecution();
void deinitExecution();
- void setClipBlack(float value) {this->clipBlack = value;}
- void setClipWhite(float value) {this->clipWhite = value;}
-
void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]);
};
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index e97f3195f47..7567d40d9a5 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -3095,7 +3095,7 @@ static void def_cmp_keying(StructRNA *srna)
RNA_def_struct_sdna_from(srna, "NodeKeyingData", "storage");
- prop = RNA_def_property(srna, "despill_factor", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "despill_factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "despill_factor");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Despill", "");