diff options
Diffstat (limited to 'source/blender/compositor/operations')
11 files changed, 145 insertions, 36 deletions
diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp index 43f491ad2d9..56527da47bc 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.cpp +++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp @@ -50,12 +50,16 @@ CompositorOperation::CompositorOperation() : NodeOperation() this->m_depthInput = NULL; this->m_ignoreAlpha = false; + this->m_active = false; this->m_sceneName[0] = '\0'; } void CompositorOperation::initExecution() { + if (!this->m_active) + return; + // When initializing the tree during initial load the width and height can be zero. this->m_imageInput = getInputSocketReader(0); this->m_alphaInput = getInputSocketReader(1); @@ -70,6 +74,9 @@ void CompositorOperation::initExecution() void CompositorOperation::deinitExecution() { + if (!this->m_active) + return; + if (!isBreaked()) { Render *re = RE_GetRender(this->m_sceneName); RenderResult *rr = RE_AcquireResultWrite(re); @@ -136,23 +143,63 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber) int x; int y; bool breaked = false; + int dx = 0, dy = 0; + + const RenderData *rd = this->m_rd; + + if (rd->mode & R_BORDER && rd->mode & R_CROP) { + /*! + When using cropped render result, need to re-position area of interest, + so it'll natch bounds of render border within frame. By default, canvas + will be centered between full frame and cropped frame, so we use such + scheme to map cropped coordinates to full-frame coordinates + + ^ Y + | Width + +------------------------------------------------+ + | | + | | + | Centered canvas, we map coordinate from it | + | +------------------+ | + | | | | H + | | | | e + | +------------------+ . Center | | i + | | | | | | g + | | | | | | h + | |....dx.... +------|-----------+ | t + | | . dy | | + | +------------------+ | + | Render border, we map coordinates to it | + | | X + +------------------------------------------------+----> + Full frame + */ + + int full_width = rd->xsch * rd->size / 100; + int full_height =rd->ysch * rd->size / 100; + + dx = rd->border.xmin * full_width - (full_width - this->getWidth()) / 2.0f; + dy = rd->border.ymin * full_height - (full_height - this->getHeight()) / 2.0f; + } for (y = y1; y < y2 && (!breaked); y++) { for (x = x1; x < x2 && (!breaked); x++) { - this->m_imageInput->read(color, x, y, COM_PS_NEAREST); + int input_x = x + dx, input_y = y + dy; + + this->m_imageInput->read(color, input_x, input_y, COM_PS_NEAREST); if (this->m_ignoreAlpha) { color[3] = 1.0f; } else { if (this->m_alphaInput != NULL) { - this->m_alphaInput->read(&(color[3]), x, y, COM_PS_NEAREST); + this->m_alphaInput->read(&(color[3]), input_x, input_y, COM_PS_NEAREST); } } copy_v4_v4(buffer + offset4, color); if (this->m_depthInput != NULL) { - this->m_depthInput->read(color, x, y, COM_PS_NEAREST); + this->m_depthInput->read(color, input_x, input_y, COM_PS_NEAREST); zbuffer[offset] = color[0]; } offset4 += COM_NUMBER_OF_CHANNELS; diff --git a/source/blender/compositor/operations/COM_CompositorOperation.h b/source/blender/compositor/operations/COM_CompositorOperation.h index 27d29664610..d33e89ed742 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.h +++ b/source/blender/compositor/operations/COM_CompositorOperation.h @@ -66,19 +66,28 @@ private: */ SocketReader *m_depthInput; - /* Ignore any alpha input */ + /** + * @brief Ignore any alpha input + */ bool m_ignoreAlpha; + /** + * @brief operation is active for calculating final compo result + */ + bool m_active; public: CompositorOperation(); + const bool isActiveCompositorOutput() const { return this->m_active; } void executeRegion(rcti *rect, unsigned int tileNumber); void setSceneName(const char *sceneName) { BLI_strncpy(this->m_sceneName, sceneName, sizeof(this->m_sceneName)); } void setRenderData(const RenderData *rd) { this->m_rd = rd; } - bool isOutputOperation(bool rendering) const { return true; } + bool isOutputOperation(bool rendering) const { return this->isActiveCompositorOutput(); } void initExecution(); void deinitExecution(); const CompositorPriority getRenderPriority() const { return COM_PRIORITY_MEDIUM; } void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); void setIgnoreAlpha(bool value) { this->m_ignoreAlpha = value; } + void setActive(bool active) { this->m_active = active; } }; #endif + diff --git a/source/blender/compositor/operations/COM_CropOperation.cpp b/source/blender/compositor/operations/COM_CropOperation.cpp index 4f9cd771988..844d23db2ac 100644 --- a/source/blender/compositor/operations/COM_CropOperation.cpp +++ b/source/blender/compositor/operations/COM_CropOperation.cpp @@ -119,7 +119,7 @@ void CropImageOperation::determineResolution(unsigned int resolution[2], unsigne void CropImageOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) { - if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) { + if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) { this->m_inputOperation->read(output, (x + this->m_xmin), (y + this->m_ymin), sampler); } else { diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp index 2d662c1061e..c236c73e50f 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp @@ -62,7 +62,6 @@ void GaussianBokehBlurOperation::updateGauss() int n; float *dgauss; float *ddgauss; - float val; int j, i; const float width = this->getWidth(); const float height = this->getHeight(); @@ -84,13 +83,15 @@ void GaussianBokehBlurOperation::updateGauss() this->m_radx = ceil(radxf); this->m_rady = ceil(radyf); - - n = (2 * this->m_radx + 1) * (2 * this->m_rady + 1); + + int ddwidth = 2 * this->m_radx + 1; + int ddheight = 2 * this->m_rady + 1; + n = ddwidth * ddheight; /* create a full filter image */ ddgauss = (float *)MEM_mallocN(sizeof(float) * n, __func__); dgauss = ddgauss; - val = 0.0f; + float sum = 0.0f; for (j = -this->m_rady; j <= this->m_rady; j++) { for (i = -this->m_radx; i <= this->m_radx; i++, dgauss++) { float fj = (float)j / radyf; @@ -98,16 +99,19 @@ void GaussianBokehBlurOperation::updateGauss() float dist = sqrt(fj * fj + fi * fi); *dgauss = RE_filter_value(this->m_data->filtertype, dist); - val += *dgauss; + sum += *dgauss; } } - if (val != 0.0f) { - val = 1.0f / val; - for (j = n - 1; j >= 0; j--) { - ddgauss[j] *= val; - } + if (sum > 0.0f) { + /* normalize */ + float norm = 1.0f / sum; + for (j = n - 1; j >= 0; j--) + ddgauss[j] *= norm; + } + else { + int center = m_rady * ddwidth + m_radx; + ddgauss[center] = 1.0f; } - else ddgauss[4] = 1.0f; this->m_gausstab = ddgauss; } diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cpp b/source/blender/compositor/operations/COM_MovieClipOperation.cpp index 74761f00e1f..a74f2c7299b 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieClipOperation.cpp @@ -30,9 +30,8 @@ extern "C" { } #include "BKE_image.h" -MovieClipOperation::MovieClipOperation() : NodeOperation() +MovieClipBaseOperation::MovieClipBaseOperation() : NodeOperation() { - this->addOutputSocket(COM_DT_COLOR); this->m_movieClip = NULL; this->m_movieClipBuffer = NULL; this->m_movieClipUser = NULL; @@ -42,7 +41,7 @@ MovieClipOperation::MovieClipOperation() : NodeOperation() } -void MovieClipOperation::initExecution() +void MovieClipBaseOperation::initExecution() { if (this->m_movieClip) { BKE_movieclip_user_set_frame(this->m_movieClipUser, this->m_framenumber); @@ -63,7 +62,7 @@ void MovieClipOperation::initExecution() } } -void MovieClipOperation::deinitExecution() +void MovieClipBaseOperation::deinitExecution() { if (this->m_movieClipBuffer) { IMB_freeImBuf(this->m_movieClipBuffer); @@ -72,7 +71,7 @@ void MovieClipOperation::deinitExecution() } } -void MovieClipOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) +void MovieClipBaseOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) { resolution[0] = 0; resolution[1] = 0; @@ -87,7 +86,7 @@ void MovieClipOperation::determineResolution(unsigned int resolution[2], unsigne } } -void MovieClipOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MovieClipBaseOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) { if (this->m_movieClipBuffer == NULL || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) { zero_v4(output); @@ -106,3 +105,22 @@ void MovieClipOperation::executePixel(float output[4], float x, float y, PixelSa } } } + +MovieClipOperation::MovieClipOperation() : MovieClipBaseOperation() +{ + this->addOutputSocket(COM_DT_COLOR); +} + +MovieClipAlphaOperation::MovieClipAlphaOperation() : MovieClipBaseOperation() +{ + this->addOutputSocket(COM_DT_VALUE); +} + +void MovieClipAlphaOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +{ + MovieClipBaseOperation::executePixel(output, x, y, sampler); + output[0] = output[3]; + output[1] = 0.0f; + output[2] = 0.0f; + output[3] = 0.0f; +} diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.h b/source/blender/compositor/operations/COM_MovieClipOperation.h index 7cce42f6727..a368dca423c 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.h +++ b/source/blender/compositor/operations/COM_MovieClipOperation.h @@ -30,11 +30,9 @@ #include "IMB_imbuf_types.h" /** - * Base class for all renderlayeroperations - * - * @todo: rename to operation. + * Base class for movie clip */ -class MovieClipOperation : public NodeOperation { +class MovieClipBaseOperation : public NodeOperation { protected: MovieClip *m_movieClip; MovieClipUser *m_movieClipUser; @@ -50,7 +48,7 @@ protected: void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); public: - MovieClipOperation(); + MovieClipBaseOperation(); void initExecution(); void deinitExecution(); @@ -62,4 +60,15 @@ public: void executePixel(float output[4], float x, float y, PixelSampler sampler); }; +class MovieClipOperation : public MovieClipBaseOperation { +public: + MovieClipOperation(); +}; + +class MovieClipAlphaOperation : public MovieClipBaseOperation { +public: + MovieClipAlphaOperation(); + void executePixel(float output[4], float x, float y, PixelSampler sampler); +}; + #endif diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl b/source/blender/compositor/operations/COM_OpenCLKernels.cl index 8cc25fc3360..d7a81001531 100644 --- a/source/blender/compositor/operations/COM_OpenCLKernels.cl +++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl @@ -112,7 +112,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 * scalar; + size = min(read_imagef(inputSize, SAMPLER_NEAREST, inputCoordinate).s0 * scalar, size_center); if (size > threshold) { if (size >= fabs(dx) && size >= fabs(dy)) { float2 uv = {256.0f + dx * 255.0f / size, diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp index 47b69ec87f9..15e5ab947d4 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp +++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp @@ -166,7 +166,7 @@ OutputOpenExrLayer::OutputOpenExrLayer(const char *name_, DataType datatype_) } OutputOpenExrMultiLayerOperation::OutputOpenExrMultiLayerOperation( - const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec) + const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec) { this->m_rd = rd; this->m_tree = tree; diff --git a/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp b/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp index 2ca499683d3..3421b0a2b34 100644 --- a/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp @@ -37,6 +37,7 @@ RenderLayersBaseProg::RenderLayersBaseProg(int renderpass, int elementsize) : No this->setScene(NULL); this->m_inputBuffer = NULL; this->m_elementsize = elementsize; + this->m_rd = NULL; } @@ -111,14 +112,29 @@ void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, Pi void RenderLayersBaseProg::executePixel(float output[4], float x, float y, PixelSampler sampler) { - int ix = x; - int iy = y; - + const RenderData *rd = this->m_rd; + + int dx = 0, dy = 0; + + if (rd->mode & R_BORDER && rd->mode & R_CROP) { + /* see comment in executeRegion describing coordinate mapping, + * here it simply goes other way around + */ + int full_width = rd->xsch * rd->size / 100; + int full_height = rd->ysch * rd->size / 100; + + dx = rd->border.xmin * full_width - (full_width - this->getWidth()) / 2.0f; + dy = rd->border.ymin * full_height - (full_height - this->getHeight()) / 2.0f; + } + + int ix = x - dx; + int iy = y - dy; + if (this->m_inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) { zero_v4(output); } else { - doInterpolation(output, x, y, sampler); + doInterpolation(output, ix, iy, sampler); } } diff --git a/source/blender/compositor/operations/COM_RenderLayersBaseProg.h b/source/blender/compositor/operations/COM_RenderLayersBaseProg.h index 3916862a0b3..84d6c1ee188 100644 --- a/source/blender/compositor/operations/COM_RenderLayersBaseProg.h +++ b/source/blender/compositor/operations/COM_RenderLayersBaseProg.h @@ -63,7 +63,12 @@ private: int m_renderpass; int m_elementsize; - + + /** + * @brief render data used for active rendering + */ + const RenderData *m_rd; + protected: /** * Constructor @@ -89,6 +94,7 @@ public: */ void setScene(Scene *scene) { this->m_scene = scene; } Scene *getScene() { return this->m_scene; } + void setRenderData(const RenderData *rd) { this->m_rd = rd; } void setLayerId(short layerId) { this->m_layerId = layerId; } short getLayerId() { return this->m_layerId; } void initExecution(); diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp index 61720c7676d..03031e0f764 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -146,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] * scalar; + float size = min(inputSizeFloatBuffer[offsetNxNy] * scalar, size_center); if (size > this->m_threshold) { float dx = nx - x; if (size > fabsf(dx) && size > fabsf(dy)) { |