diff options
Diffstat (limited to 'source/blender/compositor/operations')
-rw-r--r-- | source/blender/compositor/operations/COM_DenoiseOperation.cpp | 154 | ||||
-rw-r--r-- | source/blender/compositor/operations/COM_DenoiseOperation.h | 71 |
2 files changed, 225 insertions, 0 deletions
diff --git a/source/blender/compositor/operations/COM_DenoiseOperation.cpp b/source/blender/compositor/operations/COM_DenoiseOperation.cpp new file mode 100644 index 00000000000..af568490c72 --- /dev/null +++ b/source/blender/compositor/operations/COM_DenoiseOperation.cpp @@ -0,0 +1,154 @@ +/* + * Copyright 2019, 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: + * Stefan Werner + */ + +#include "COM_DenoiseOperation.h" +#include "BLI_math.h" +#ifdef WITH_OPENIMAGEDENOISE +# include <OpenImageDenoise/oidn.hpp> +#endif +#include <iostream> + +DenoiseOperation::DenoiseOperation() : SingleThreadedOperation() +{ + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VECTOR); + this->addOutputSocket(COM_DT_COLOR); + this->m_settings = NULL; +} +void DenoiseOperation::initExecution() +{ + SingleThreadedOperation::initExecution(); + this->m_inputProgramColor = getInputSocketReader(0); + this->m_inputProgramAlbedo = getInputSocketReader(1); + this->m_inputProgramNormal = getInputSocketReader(2); +} + +void DenoiseOperation::deinitExecution() +{ + this->m_inputProgramColor = NULL; + this->m_inputProgramAlbedo = NULL; + this->m_inputProgramNormal = NULL; + SingleThreadedOperation::deinitExecution(); +} + +MemoryBuffer *DenoiseOperation::createMemoryBuffer(rcti *rect2) +{ + MemoryBuffer *tileColor = (MemoryBuffer *)this->m_inputProgramColor->initializeTileData(rect2); + MemoryBuffer *tileAlbedo = (MemoryBuffer *)this->m_inputProgramAlbedo->initializeTileData(rect2); + MemoryBuffer *tileNormal = (MemoryBuffer *)this->m_inputProgramNormal->initializeTileData(rect2); + rcti rect; + rect.xmin = 0; + rect.ymin = 0; + rect.xmax = getWidth(); + rect.ymax = getHeight(); + MemoryBuffer *result = new MemoryBuffer(COM_DT_COLOR, &rect); + float *data = result->getBuffer(); + this->generateDenoise(data, tileColor, tileAlbedo, tileNormal, this->m_settings); + return result; +} + +bool DenoiseOperation::determineDependingAreaOfInterest(rcti * /*input*/, + ReadBufferOperation *readOperation, + rcti *output) +{ + if (isCached()) { + return false; + } + else { + rcti newInput; + newInput.xmax = this->getWidth(); + newInput.xmin = 0; + newInput.ymax = this->getHeight(); + newInput.ymin = 0; + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); + } +} + +void DenoiseOperation::generateDenoise(float *data, + MemoryBuffer *inputTileColor, + MemoryBuffer *inputTileAlbedo, + MemoryBuffer *inputTileNormal, + NodeDenoise *settings) +{ + float *inputBufferColor = inputTileColor->getBuffer(); + BLI_assert(inputBufferColor); + if (!inputBufferColor) { + return; + } +#ifdef WITH_OPENIMAGEDENOISE + oidn::DeviceRef device = oidn::newDevice(); + device.commit(); + + oidn::FilterRef filter = device.newFilter("RT"); + filter.setImage("color", + inputBufferColor, + oidn::Format::Float3, + inputTileColor->getWidth(), + inputTileColor->getHeight(), + 0, + 4 * sizeof(float)); + if (inputTileAlbedo && inputTileAlbedo->getBuffer()) { + filter.setImage("albedo", + inputTileAlbedo->getBuffer(), + oidn::Format::Float3, + inputTileAlbedo->getWidth(), + inputTileAlbedo->getHeight(), + 0, + 4 * sizeof(float)); + } + if (inputTileNormal && inputTileNormal->getBuffer()) { + filter.setImage("normal", + inputTileNormal->getBuffer(), + oidn::Format::Float3, + inputTileNormal->getWidth(), + inputTileNormal->getHeight(), + 0, + 3 * sizeof(float)); + } + filter.setImage("output", + data, + oidn::Format::Float3, + inputTileColor->getWidth(), + inputTileColor->getHeight(), + 0, + 4 * sizeof(float)); + + BLI_assert(settings); + if (settings) { + filter.set("hdr", settings->hdr); + filter.set("srgb", false); + } + + filter.commit(); + filter.execute(); + + /* copy the alpha channel, OpenImageDenoise currently only supports RGB */ + size_t numPixels = inputTileColor->getWidth() * inputTileColor->getHeight(); + for (size_t i = 0; i < numPixels; ++i) { + data[i * 4 + 3] = inputBufferColor[i * 4 + 3]; + } +#else + ::memcpy(data, + inputBufferColor, + inputTileColor->getWidth() * inputTileColor->getHeight() * sizeof(float) * 4); +#endif +} diff --git a/source/blender/compositor/operations/COM_DenoiseOperation.h b/source/blender/compositor/operations/COM_DenoiseOperation.h new file mode 100644 index 00000000000..6e19bd6034a --- /dev/null +++ b/source/blender/compositor/operations/COM_DenoiseOperation.h @@ -0,0 +1,71 @@ +/* + * Copyright 2019, 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: + * Stefan Werner + */ + +#ifndef __COM_DENOISEBASEOPERATION_H__ +#define __COM_DENOISEBASEOPERATION_H__ + +#include "COM_SingleThreadedOperation.h" +#include "DNA_node_types.h" + +class DenoiseOperation : public SingleThreadedOperation { + private: + /** + * \brief Cached reference to the input programs + */ + SocketReader *m_inputProgramColor; + SocketReader *m_inputProgramAlbedo; + SocketReader *m_inputProgramNormal; + + /** + * \brief settings of the denoise node. + */ + NodeDenoise *m_settings; + + public: + DenoiseOperation(); + /** + * Initialize the execution + */ + void initExecution(); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setDenoiseSettings(NodeDenoise *settings) + { + this->m_settings = settings; + } + bool determineDependingAreaOfInterest(rcti *input, + ReadBufferOperation *readOperation, + rcti *output); + + protected: + void generateDenoise(float *data, + MemoryBuffer *inputTileColor, + MemoryBuffer *inputTileAlbedo, + MemoryBuffer *inputTileNormal, + NodeDenoise *settings); + + MemoryBuffer *createMemoryBuffer(rcti *rect); +}; +#endif |