compositor: bokeh blur size input can now be an image, in this case it uses VariableS...
authorCampbell Barton <ideasman42@gmail.com>
Fri, 10 Aug 2012 15:31:54 +0000 (15:31 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 10 Aug 2012 15:31:54 +0000 (15:31 +0000)
updated opencl too.

source/blender/compositor/nodes/COM_BokehBlurNode.cpp
source/blender/compositor/operations/COM_OpenCLKernels.cl
source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp
source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h

index f45572fe4aefbf2d866ed2c51a67ccbc59f8ea3c..434fcf2a6089ff1e0300f501702e41b0e5444fc5 100644 (file)
@@ -36,24 +36,42 @@ BokehBlurNode::BokehBlurNode(bNode *editorNode) : Node(editorNode)
 
 void BokehBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
 {
-       BokehBlurOperation *operation = new BokehBlurOperation();
        InputSocket *inputSizeSocket = this->getInputSocket(2);
        bool connectedSizeSocket = inputSizeSocket->isConnected();
 
-       const bNodeSocket *sock = this->getInputSocket(2)->getbNodeSocket();
-       const float size = ((const bNodeSocketValueFloat *)sock->default_value)->value;
+       if (connectedSizeSocket) {
+               VariableSizeBokehBlurOperation *operation = new VariableSizeBokehBlurOperation();
 
-       this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
-       this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
-       this->getInputSocket(2)->relinkConnections(operation->getInputSocket(3), 2, graph);
-       this->getInputSocket(3)->relinkConnections(operation->getInputSocket(2), 3, graph);
-       //operation->setSize(((bNodeSocketValueFloat *)this->getInputSocket(2)->getbNodeSocket()->default_value)->value);
-       operation->setQuality(context->getQuality());
-       operation->setbNode(this->getbNode());
-       graph->addOperation(operation);
-       this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
+               this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
+               this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
+               this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), 2, graph);
+               operation->setQuality(context->getQuality());
+               operation->setbNode(this->getbNode());
+               graph->addOperation(operation);
+               this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
+
+               operation->setThreshold(0.0f);
+
+               /* TODO, we need to know the max input pixel of the input, this value is arbitrary! */
+               operation->setMaxBlur(100.0f);
+               operation->setDoScaleSize(true);
+       }
+       else {
+               BokehBlurOperation *operation = new BokehBlurOperation();
+
+               const bNodeSocket *sock = this->getInputSocket(2)->getbNodeSocket();
+               const float size = ((const bNodeSocketValueFloat *)sock->default_value)->value;
+
+               this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
+               this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
+               this->getInputSocket(2)->relinkConnections(operation->getInputSocket(3), 2, graph);
+               this->getInputSocket(3)->relinkConnections(operation->getInputSocket(2), 3, graph);
+               //operation->setSize(((bNodeSocketValueFloat *)this->getInputSocket(2)->getbNodeSocket()->default_value)->value);
+               operation->setQuality(context->getQuality());
+               operation->setbNode(this->getbNode());
+               graph->addOperation(operation);
+               this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
 
-       if (!connectedSizeSocket) {
                operation->setSize(size);
        }
 }
index 9a89fe21414dfa1ae3491f7e0884ad2d86d4ec22..7366db19444e2f4f728dde985945a9b5e5804055 100644 (file)
@@ -78,7 +78,7 @@ __kernel void bokehBlurKernel(__read_only image2d_t boundingBox, __read_only ima
 __kernel void defocusKernel(__read_only image2d_t inputImage, __read_only image2d_t bokehImage, 
                                        __read_only image2d_t inputSize,
                                        __write_only image2d_t output, int2 offsetInput, int2 offsetOutput, 
-                                       int step, int maxBlur, float threshold, int2 dimension, int2 offset
+                                       int step, int maxBlurScalar, float threshold, int2 dimension, int2 offset, float scalar
 {
        float4 color = {1.0f, 0.0f, 0.0f, 1.0f};
        int2 coords = {get_global_id(0), get_global_id(1)};
@@ -92,14 +92,14 @@ __kernel void defocusKernel(__read_only image2d_t inputImage, __read_only image2
        float4 multiplier_accum = {1.0f, 1.0f, 1.0f, 1.0f};
        float4 color_accum;
        
-       int minx = max(realCoordinate.s0 - maxBlur, 0);
-       int miny = max(realCoordinate.s1 - maxBlur, 0);
-       int maxx = min(realCoordinate.s0 + maxBlur, dimension.s0);
-       int maxy = min(realCoordinate.s1 + maxBlur, dimension.s1);
+       int minx = max(realCoordinate.s0 - maxBlurScalar, 0);
+       int miny = max(realCoordinate.s1 - maxBlurScalar, 0);
+       int maxx = min(realCoordinate.s0 + maxBlurScalar, dimension.s0);
+       int maxy = min(realCoordinate.s1 + maxBlurScalar, dimension.s1);
        
        {
                int2 inputCoordinate = realCoordinate - offsetInput;
-               float size_center = read_imagef(inputSize, SAMPLER_NEAREST, inputCoordinate).s0;
+               float size_center = read_imagef(inputSize, SAMPLER_NEAREST, inputCoordinate).s0 * scalar;
                color_accum = read_imagef(inputImage, SAMPLER_NEAREST, inputCoordinate);
                readColor = color_accum;
 
@@ -111,7 +111,7 @@ __kernel void defocusKernel(__read_only image2d_t inputImage, __read_only image2
                                        float dx = nx - realCoordinate.s0;
                                        if (dx != 0 || dy != 0) {
                                                inputCoordinate.s0 = nx - offsetInput.s0;
-                                               size = read_imagef(inputSize, SAMPLER_NEAREST, inputCoordinate).s0;
+                                               size = read_imagef(inputSize, SAMPLER_NEAREST, inputCoordinate).s0 * scalar;
                                                if (size > threshold) {
                                                        if (size >= fabs(dx) && size >= fabs(dy)) {
                                                                float2 uv = {256.0f + dx * 255.0f / size,
index e4f88dc7659f4238f985b819f08df7e153d500b3..7ccc91072bcd9da8b73219de99b043309b3300ff 100644 (file)
@@ -45,6 +45,7 @@ VariableSizeBokehBlurOperation::VariableSizeBokehBlurOperation() : NodeOperation
        this->m_inputSizeProgram = NULL;
        this->m_maxBlur = 32.0f;
        this->m_threshold = 1.0f;
+       this->m_do_size_scale = false;
 #ifdef COM_DEFOCUS_SEARCH
        this->m_inputSearchProgram = NULL;
 #endif
@@ -66,7 +67,7 @@ struct VariableSizeBokehBlurTileData
        MemoryBuffer *color;
        MemoryBuffer *bokeh;
        MemoryBuffer *size;
-       int maxBlur;
+       int maxBlurScalar;
 };
 
 void *VariableSizeBokehBlurOperation::initializeTileData(rcti *rect)
@@ -79,8 +80,12 @@ void *VariableSizeBokehBlurOperation::initializeTileData(rcti *rect)
 
        rcti rect2;
        this->determineDependingAreaOfInterest(rect, (ReadBufferOperation *)this->m_inputSizeProgram, &rect2);
-       data->maxBlur = (int)data->size->getMaximumValue(&rect2);
-       CLAMP(data->maxBlur, 1.0f, this->m_maxBlur);
+
+       const float max_dim = max(m_width, m_height);
+       const float scalar = this->m_do_size_scale ? (max_dim / 100.0f) : 1.0f;
+
+       data->maxBlurScalar = (int)(data->size->getMaximumValue(&rect2) * scalar);
+       CLAMP(data->maxBlurScalar, 1.0f, this->m_maxBlur);
        return data;
 }
 
@@ -103,7 +108,13 @@ void VariableSizeBokehBlurOperation::executePixel(float output[4], int x, int y,
        float tempSize[4];
        float multiplier_accum[4];
        float color_accum[4];
-       int maxBlur = tileData->maxBlur;
+
+       const float max_dim = max(m_width, m_height);
+       const float scalar = this->m_do_size_scale ? (max_dim / 100.0f) : 1.0f;
+       int maxBlurScalar = tileData->maxBlurScalar;
+
+       BLI_assert(inputBokehBuffer->getWidth()  == COM_BLUR_BOKEH_PIXELS);
+       BLI_assert(inputBokehBuffer->getHeight() == COM_BLUR_BOKEH_PIXELS);
 
 #ifdef COM_DEFOCUS_SEARCH
        float search[4];
@@ -113,10 +124,10 @@ void VariableSizeBokehBlurOperation::executePixel(float output[4], int x, int y,
        int maxx = search[2];
        int maxy = search[3];
 #else
-       int minx = max(x - maxBlur, 0);
-       int miny = max(y - maxBlur, 0);
-       int maxx = min(x + maxBlur, (int)m_width);
-       int maxy = min(y + maxBlur, (int)m_height);
+       int minx = max(x - maxBlurScalar, 0);
+       int miny = max(y - maxBlurScalar, 0);
+       int maxx = min(x + maxBlurScalar, (int)m_width);
+       int maxy = min(y + maxBlurScalar, (int)m_height);
 #endif
        {
                inputSizeBuffer->readNoCheck(tempSize, x, y);
@@ -124,7 +135,7 @@ void VariableSizeBokehBlurOperation::executePixel(float output[4], int x, int y,
 
                copy_v4_v4(color_accum, readColor);
                copy_v4_fl(multiplier_accum, 1.0f);
-               float size_center = tempSize[0];
+               float size_center = tempSize[0] * scalar;
                
                const int addXStep = QualityStepHelper::getStep() * COM_NUMBER_OF_CHANNELS;
                
@@ -135,7 +146,7 @@ void VariableSizeBokehBlurOperation::executePixel(float output[4], int x, int y,
                                int offsetNxNy = offsetNy + (minx * COM_NUMBER_OF_CHANNELS);
                                for (int nx = minx; nx < maxx; nx += QualityStepHelper::getStep()) {
                                        if (nx != x || ny != y) {
-                                               float size = inputSizeFloatBuffer[offsetNxNy];
+                                               float size = inputSizeFloatBuffer[offsetNxNy] * scalar;
                                                if (size > this->m_threshold) {
                                                        float dx = nx - x;
                                                        if (size > fabsf(dx) && size > fabsf(dy)) {
@@ -182,7 +193,11 @@ void VariableSizeBokehBlurOperation::executeOpenCL(OpenCLDevice *device,
        cl_float threshold = this->m_threshold;
        
        MemoryBuffer *sizeMemoryBuffer = (MemoryBuffer *)this->m_inputSizeProgram->getInputMemoryBuffer(inputMemoryBuffers);
-       maxBlur = (cl_int)sizeMemoryBuffer->getMaximumValue();
+
+       const float max_dim = max(m_width, m_height);
+       cl_float scalar = this->m_do_size_scale ? (max_dim / 100.0f) : 1.0f;
+
+       maxBlur = (cl_int)sizeMemoryBuffer->getMaximumValue() * scalar;
        maxBlur = MIN2(maxBlur, this->m_maxBlur);
 
        device->COM_clAttachMemoryBufferToKernelParameter(defocusKernel, 0, -1, clMemToCleanUp, inputMemoryBuffers, this->m_inputProgram);
@@ -193,9 +208,10 @@ void VariableSizeBokehBlurOperation::executeOpenCL(OpenCLDevice *device,
        clSetKernelArg(defocusKernel, 6, sizeof(cl_int), &step);
        clSetKernelArg(defocusKernel, 7, sizeof(cl_int), &maxBlur);
        clSetKernelArg(defocusKernel, 8, sizeof(cl_float), &threshold);
-       device->COM_clAttachSizeToKernelParameter(defocusKernel, 9, this);
+       clSetKernelArg(defocusKernel, 9, sizeof(cl_float), &scalar);
+       device->COM_clAttachSizeToKernelParameter(defocusKernel, 10, this);
        
-       device->COM_clEnqueueRange(defocusKernel, outputMemoryBuffer, 10, this);
+       device->COM_clEnqueueRange(defocusKernel, outputMemoryBuffer, 11, this);
 }
 
 void VariableSizeBokehBlurOperation::deinitExecution()
@@ -213,10 +229,14 @@ bool VariableSizeBokehBlurOperation::determineDependingAreaOfInterest(rcti *inpu
        rcti newInput;
        rcti bokehInput;
 
-       newInput.xmax = input->xmax + this->m_maxBlur + 2;
-       newInput.xmin = input->xmin - this->m_maxBlur + 2;
-       newInput.ymax = input->ymax + this->m_maxBlur - 2;
-       newInput.ymin = input->ymin - this->m_maxBlur - 2;
+       const float max_dim = max(m_width, m_height);
+       const float scalar = this->m_do_size_scale ? (max_dim / 100.0f) : 1.0f;
+       int maxBlurScalar = this->m_maxBlur * scalar;
+
+       newInput.xmax = input->xmax + maxBlurScalar + 2;
+       newInput.xmin = input->xmin - maxBlurScalar + 2;
+       newInput.ymax = input->ymax + maxBlurScalar - 2;
+       newInput.ymin = input->ymin - maxBlurScalar - 2;
        bokehInput.xmax = COM_BLUR_BOKEH_PIXELS;
        bokehInput.xmin = 0;
        bokehInput.ymax = COM_BLUR_BOKEH_PIXELS;
index 1cab4a60af0844dc5779cad76bc8d6798d1ab4ab..d4025692549c0b648bcc51674c1905b97da500a6 100644 (file)
@@ -31,6 +31,7 @@ class VariableSizeBokehBlurOperation : public NodeOperation, public QualityStepH
 private:
        int m_maxBlur;
        float m_threshold;
+       bool m_do_size_scale;  /* scale size, matching 'BokehBlurNode' */
        SocketReader *m_inputProgram;
        SocketReader *m_inputBokehProgram;
        SocketReader *m_inputSizeProgram;
@@ -66,6 +67,8 @@ public:
 
        void setThreshold(float threshold) { this->m_threshold = threshold; }
 
+       void setDoScaleSize(bool scale_size) { this->m_do_size_scale = scale_size; }
+
        void executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp);
 };