Compositor: Added denoising node

This node is built on Intel's OpenImageDenoise library.
Other denoisers could be integrated, for example Lukas' Cycles denoiser.

Compositor: Made OpenImageDenoise optional, added CMake and build_env files to find OIDN

Compositor: Fixed some warnings in the denoising operator

build_environment: Updated OpenImageDenoise to 0.8.1

build_environment: Updated OpenImageDenoise in `make deps` for macOS

Reviewers: sergey, jbakker, brecht

Reviewed By: brecht

Subscribers: YAFU, LazyDodo, Zen_YS, slumber, samgreen, tjvoll, yeus, ponomarovmax, getrad, coder.kalyan, vitos1k, Yegor, DeepBlender, kumaran7, Darkfie9825, aliasguru, aafra, ace_dragon, juang3d, pandrodor, cdog, lordodin, jtheninja, mavek, marcog, 5k1n2, Atair, rawalanche, 0o00o0oo, filibis, poor, lukasstockner97

Tags: #compositing

Differential Revision: https://developer.blender.org/D4304
This commit is contained in:
Brecht Van Lommel 2019-08-14 15:30:26 +02:00 committed by Stefan Werner
parent 1845f0ee8b
commit 5489611e53
32 changed files with 759 additions and 3 deletions

@ -237,6 +237,7 @@ option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ${_init_OPENCOLO
# Compositor
option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON)
option(WITH_OPENIMAGEDENOISE "Enable the OpenImageDenoise compositing node" OFF)
option(WITH_OPENSUBDIV "Enable OpenSubdiv for surface subdivision" ${_init_OPENSUBDIV})
@ -1760,6 +1761,7 @@ if(FIRST_RUN)
info_cfg_option(WITH_CYCLES)
info_cfg_option(WITH_FREESTYLE)
info_cfg_option(WITH_OPENCOLORIO)
info_cfg_option(WITH_OPENIMAGEDENOISE)
info_cfg_option(WITH_OPENVDB)
info_cfg_option(WITH_ALEMBIC)

@ -97,6 +97,7 @@ if(UNIX AND NOT APPLE)
else()
include(cmake/pugixml.cmake)
endif()
include(cmake/openimagedenoise.cmake)
if(WITH_WEBP)
include(cmake/webp.cmake)

@ -166,6 +166,8 @@ harvest(openimageio/bin openimageio/bin "maketx")
harvest(openimageio/bin openimageio/bin "oiiotool")
harvest(openimageio/include openimageio/include "*")
harvest(openimageio/lib openimageio/lib "*.a")
harvest(openimagedenoise/include openimagedenoise/include "*")
harvest(openimagedenoise/lib openimagedenoise/lib "*.a")
harvest(openjpeg/include/openjpeg-2.3 openjpeg/include "*.h")
harvest(openjpeg/lib openjpeg/lib "*.a")
harvest(opensubdiv/include opensubdiv/include "*.h")

@ -0,0 +1,61 @@
# ***** BEGIN GPL LICENSE BLOCK *****
#
# 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.
#
# ***** END GPL LICENSE BLOCK *****
set(OIDN_EXTRA_ARGS
-DWITH_EXAMPLE=OFF
-DWITH_TEST=OFF
-DTBB_ROOT=${LIBDIR}/tbb
-DTBB_STATIC_LIB=ON
-DOIDN_STATIC_LIB=ON
)
ExternalProject_Add(external_openimagedenoise
URL ${OIDN_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${OIDN_HASH}
PREFIX ${BUILD_DIR}/openimagedenoise
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openimagedenoise ${DEFAULT_CMAKE_FLAGS} ${OIDN_EXTRA_ARGS}
PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/openimagedenoise/src/external_openimagedenoise < ${PATCH_DIR}/openimagedenoise.diff
INSTALL_DIR ${LIBDIR}/openimagedenoise
)
add_dependencies(
external_openimagedenoise
external_tbb
)
if(WIN32)
if(BUILD_MODE STREQUAL Release)
ExternalProject_Add_Step(external_openimagedenoise after_install
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openimagedenoise/include ${HARVEST_TARGET}/openimagedenoise/include
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/openimagedenoise.lib ${HARVEST_TARGET}/openimagedenoise/lib/openimagedenoise.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/common.lib ${HARVEST_TARGET}/openimagedenoise/lib/common.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/mkldnn.lib ${HARVEST_TARGET}/openimagedenoise/lib/mkldnn.lib
DEPENDEES install
)
endif()
if(BUILD_MODE STREQUAL Debug)
ExternalProject_Add_Step(external_openimagedenoise after_install
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/openimagedenoise.lib ${HARVEST_TARGET}/openimagedenoise/lib/openimagedenoise_d.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/common.lib ${HARVEST_TARGET}/openimagedenoise/lib/common_d.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimagedenoise/lib/mkldnn.lib ${HARVEST_TARGET}/openimagedenoise/lib/mkldnn_d.lib
DEPENDEES install
)
endif()
endif()

@ -18,7 +18,7 @@
set(TBB_EXTRA_ARGS
-DTBB_BUILD_SHARED=Off
-DTBB_BUILD_TBBMALLOC=Off
-DTBB_BUILD_TBBMALLOC=On
-DTBB_BUILD_TBBMALLOC_PROXY=Off
-DTBB_BUILD_STATIC=On
)

@ -302,3 +302,7 @@ set(SQLITE_HASH fb558c49ee21a837713c4f1e7e413309aabdd9c7)
set(EMBREE_VERSION 3.2.4)
set(EMBREE_URI https://github.com/embree/embree/archive/v${EMBREE_VERSION}.zip)
set(EMBREE_HASH 3d4a1147002ff43939d45140aa9d6fb8)
set(OIDN_VERSION 1.0.0)
set(OIDN_URI https://github.com/OpenImageDenoise/oidn/releases/download/v${OIDN_VERSION}/oidn-${OIDN_VERSION}.src.zip)
set(OIDN_HASH 19fe67b0164e8f020ac8a4f520defe60)

@ -0,0 +1,119 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 70ec895..e616b63 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -178,7 +178,9 @@ set_property(TARGET ${PROJECT_NAME} PROPERTY SOVERSION "0")
## Open Image Denoise examples
## ----------------------------------------------------------------------------
-add_subdirectory(examples)
+if(WITH_EXAMPLE)
+ add_subdirectory(examples)
+endif()
## ----------------------------------------------------------------------------
## Open Image Denoise install and packaging
Submodule mkl-dnn contains modified content
diff --git a/mkl-dnn/cmake/TBB.cmake b/mkl-dnn/cmake/TBB.cmake
index 0711e699..c14210b6 100644
--- a/mkl-dnn/cmake/TBB.cmake
+++ b/mkl-dnn/cmake/TBB.cmake
@@ -90,8 +90,8 @@ if(WIN32)
NO_DEFAULT_PATH
)
set(TBB_LIB_DIR ${TBB_ROOT}/lib/${TBB_ARCH}/${TBB_VCVER})
- find_library(TBB_LIBRARY tbb PATHS ${TBB_LIB_DIR} ${TBB_ROOT}/lib NO_DEFAULT_PATH)
- find_library(TBB_LIBRARY_MALLOC tbbmalloc PATHS ${TBB_LIB_DIR} ${TBB_ROOT}/lib NO_DEFAULT_PATH)
+ find_library(TBB_LIBRARY tbb_static PATHS ${TBB_LIB_DIR} ${TBB_ROOT}/lib NO_DEFAULT_PATH)
+ find_library(TBB_LIBRARY_MALLOC tbbmalloc_static PATHS ${TBB_LIB_DIR} ${TBB_ROOT}/lib NO_DEFAULT_PATH)
endif()
else()
@@ -138,13 +138,13 @@ else()
set(TBB_LIBRARY_MALLOC TBB_LIBRARY_MALLOC-NOTFOUND)
if(APPLE)
find_path(TBB_INCLUDE_DIR tbb/task_scheduler_init.h PATHS ${TBB_ROOT}/include NO_DEFAULT_PATH)
- find_library(TBB_LIBRARY tbb PATHS ${TBB_ROOT}/lib NO_DEFAULT_PATH)
- find_library(TBB_LIBRARY_MALLOC tbbmalloc PATHS ${TBB_ROOT}/lib NO_DEFAULT_PATH)
+ find_library(TBB_LIBRARY tbb_static PATHS ${TBB_ROOT}/lib NO_DEFAULT_PATH)
+ find_library(TBB_LIBRARY_MALLOC tbbmalloc_static PATHS ${TBB_ROOT}/lib NO_DEFAULT_PATH)
else()
find_path(TBB_INCLUDE_DIR tbb/task_scheduler_init.h PATHS ${TBB_ROOT}/include NO_DEFAULT_PATH)
set(TBB_HINTS HINTS ${TBB_ROOT}/lib/intel64/gcc4.4 ${TBB_ROOT}/lib ${TBB_ROOT}/lib64 PATHS /usr/libx86_64-linux-gnu/)
- find_library(TBB_LIBRARY tbb ${TBB_HINTS})
- find_library(TBB_LIBRARY_MALLOC tbbmalloc ${TBB_HINTS})
+ find_library(TBB_LIBRARY tbb_static ${TBB_HINTS})
+ find_library(TBB_LIBRARY_MALLOC tbbmalloc_static ${TBB_HINTS})
endif()
endif()
diff '--ignore-matching-lines=:' -ur '--exclude=*.svn*' -u -r
--- a/cmake/install.cmake 2019-08-12 18:02:20.794402575 +0200
+++ b/cmake/install.cmake 2019-08-12 18:06:07.470045703 +0200
@@ -18,6 +18,13 @@
## Install library
## ----------------------------------------------------------------------------
+if(UNIX)
+install(FILES
+ ${CMAKE_BINARY_DIR}/libOpenImageDenoise.a
+ ${CMAKE_BINARY_DIR}/libmkldnn.a
+ ${CMAKE_BINARY_DIR}/libcommon.a
+ DESTINATION ${CMAKE_INSTALL_LIBDIR})
+else()
install(TARGETS ${PROJECT_NAME}
EXPORT
${PROJECT_NAME}_Export
@@ -38,6 +45,7 @@
DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT devel
)
endif()
+endif()
## ----------------------------------------------------------------------------
## Install headers
@@ -78,6 +86,7 @@
## Install CMake configuration files
## ----------------------------------------------------------------------------
+if(NOT UNIX)
install(EXPORT ${PROJECT_NAME}_Export
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
#NAMESPACE ${PROJECT_NAME}::
@@ -92,3 +101,4 @@
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
COMPONENT devel
)
+endif()
diff '--ignore-matching-lines=:' -ur '--exclude=*.svn*' -u -r
--- a/CMakeLists.txt 2019-08-12 14:22:00.974078598 +0200
+++ b/CMakeLists.txt 2019-08-12 18:05:05.949057375 +0200
@@ -14,7 +14,11 @@
## limitations under the License. ##
## ======================================================================== ##
-cmake_minimum_required(VERSION 3.1)
+if(UNIX)
+ cmake_minimum_required(VERSION 3.1)
+else()
+ cmake_minimum_required(VERSION 3.13)
+endif()
set(OIDN_VERSION_MAJOR 1)
set(OIDN_VERSION_MINOR 0)
@@ -32,13 +36,8 @@
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
# Build as shared or static library
-if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
- option(OIDN_STATIC_LIB "Build Open Image Denoise as a static library.")
- mark_as_advanced(CLEAR OIDN_STATIC_LIB)
-else()
- set(OIDN_STATIC_LIB OFF CACHE BOOL "Build Open Image Denoise as a static library." FORCE)
- mark_as_advanced(OIDN_STATIC_LIB)
-endif()
+option(OIDN_STATIC_LIB "Build Open Image Denoise as a static library.")
+mark_as_advanced(CLEAR OIDN_STATIC_LIB)
if(OIDN_STATIC_LIB)
set(OIDN_LIB_TYPE STATIC)
else()

@ -0,0 +1,101 @@
# - Find OpenImageDenoise library
# Find the native OpenImageDenoise includes and library
# This module defines
# OPENIMAGEDENOISE_INCLUDE_DIRS, where to find oidn.h, Set when
# OPENIMAGEDENOISE is found.
# OPENIMAGEDENOISE_LIBRARIES, libraries to link against to use OpenImageDenoise.
# OPENIMAGEDENOISE_ROOT_DIR, The base directory to search for OpenImageDenoise.
# This can also be an environment variable.
# OPENIMAGEDENOISE_FOUND, If false, do not try to use OpenImageDenoise.
#
# also defined, but not for general use are
# OPENIMAGEDENOISE_LIBRARY, where to find the OpenImageDenoise library.
#=============================================================================
# Copyright 2019 Blender Foundation.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# If OPENIMAGEDENOISE_ROOT_DIR was defined in the environment, use it.
IF(NOT OPENIMAGEDENOISE_ROOT_DIR AND NOT $ENV{OPENIMAGEDENOISE_ROOT_DIR} STREQUAL "")
SET(OPENIMAGEDENOISE_ROOT_DIR $ENV{OPENIMAGEDENOISE_ROOT_DIR})
ENDIF()
SET(_openimagedenoise_SEARCH_DIRS
${OPENIMAGEDENOISE_ROOT_DIR}
/usr/local
/sw # Fink
/opt/local # DarwinPorts
/opt/lib/openimagedenoise
)
FIND_PATH(OPENIMAGEDENOISE_INCLUDE_DIR
NAMES
OpenImageDenoise/oidn.h
HINTS
${_openimagedenoise_SEARCH_DIRS}
PATH_SUFFIXES
include
)
SET(_openimagedenoise_FIND_COMPONENTS
OpenImageDenoise
common
mkldnn
)
SET(_openimagedenoise_LIBRARIES)
FOREACH(COMPONENT ${_openimagedenoise_FIND_COMPONENTS})
STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
FIND_LIBRARY(OPENIMAGEDENOISE_${UPPERCOMPONENT}_LIBRARY
NAMES
${COMPONENT}
HINTS
${_openimagedenoise_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib
)
LIST(APPEND _openimagedenoise_LIBRARIES "${OPENIMAGEDENOISE_${UPPERCOMPONENT}_LIBRARY}")
ENDFOREACH()
FIND_LIBRARY(OPENIMAGEDENOISE_LIBRARY
NAMES
OpenImageDenoise
HINTS
${_openimagedenoise_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib
)
# handle the QUIETLY and REQUIRED arguments and set OPENIMAGEDENOISE_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENIMAGEDENOISE DEFAULT_MSG
OPENIMAGEDENOISE_LIBRARY OPENIMAGEDENOISE_INCLUDE_DIR)
IF(OPENIMAGEDENOISE_FOUND)
SET(OPENIMAGEDENOISE_LIBRARIES ${_openimagedenoise_LIBRARIES})
SET(OPENIMAGEDENOISE_INCLUDE_DIRS ${OPENIMAGEDENOISE_INCLUDE_DIR})
ELSE()
SET(OPENIMAGEDENOISE_FOUND FALSE)
ENDIF()
MARK_AS_ADVANCED(
OPENIMAGEDENOISE_INCLUDE_DIR
)
FOREACH(COMPONENT ${_openimagedenoise_FIND_COMPONENTS})
STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
MARK_AS_ADVANCED(OPENIMAGEDENOISE_${UPPERCOMPONENT}_LIBRARY)
ENDFOREACH()
UNSET(_openimagedenoise_SEARCH_DIRS)
UNSET(_openimagedenoise_FIND_COMPONENTS)
UNSET(_openimagedenoise_LIBRARIES)

@ -40,6 +40,7 @@ set(WITH_AUDASPACE ON CACHE BOOL "" FORCE)
set(WITH_OPENAL ON CACHE BOOL "" FORCE)
set(WITH_OPENCOLLADA ON CACHE BOOL "" FORCE)
set(WITH_OPENCOLORIO ON CACHE BOOL "" FORCE)
set(WITH_OPENIMAGEDENOISE OFF CACHE BOOL "" FORCE)
set(WITH_OPENMP ON CACHE BOOL "" FORCE)
set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE)
set(WITH_OPENVDB ON CACHE BOOL "" FORCE)

@ -45,6 +45,7 @@ set(WITH_AUDASPACE OFF CACHE BOOL "" FORCE)
set(WITH_OPENAL OFF CACHE BOOL "" FORCE)
set(WITH_OPENCOLLADA OFF CACHE BOOL "" FORCE)
set(WITH_OPENCOLORIO OFF CACHE BOOL "" FORCE)
set(WITH_OPENIMAGEDENOISE OFF CACHE BOOL "" FORCE)
set(WITH_OPENIMAGEIO OFF CACHE BOOL "" FORCE)
set(WITH_OPENMP OFF CACHE BOOL "" FORCE)
set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE)

@ -41,6 +41,7 @@ set(WITH_AUDASPACE ON CACHE BOOL "" FORCE)
set(WITH_OPENAL ON CACHE BOOL "" FORCE)
set(WITH_OPENCOLLADA ON CACHE BOOL "" FORCE)
set(WITH_OPENCOLORIO ON CACHE BOOL "" FORCE)
set(WITH_OPENIMAGEDENOISE OFF CACHE BOOL "" FORCE)
set(WITH_OPENMP ON CACHE BOOL "" FORCE)
set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE)
set(WITH_OPENVDB ON CACHE BOOL "" FORCE)

@ -352,6 +352,9 @@ function(SETUP_LIBDIRS)
if(WITH_OPENIMAGEIO)
link_directories(${OPENIMAGEIO_LIBPATH})
endif()
if(WITH_OPENIMAGEDENOISE)
link_directories(${OPENIMAGEDENOISE_LIBPATH})
endif()
if(WITH_OPENCOLORIO)
link_directories(${OPENCOLORIO_LIBPATH})
endif()
@ -462,6 +465,9 @@ function(setup_liblinks
if(WITH_OPENIMAGEIO)
target_link_libraries(${target} ${OPENIMAGEIO_LIBRARIES})
endif()
if(WITH_OPENIMAGEDENOISE)
target_link_libraries(${target} ${OPENIMAGEDENOISE_LIBRARIES} ${TBB_LIBRARIES})
endif()
if(WITH_OPENCOLORIO)
target_link_libraries(${target} ${OPENCOLORIO_LIBRARIES})
endif()

@ -382,6 +382,19 @@ if(WITH_CYCLES_EMBREE)
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Xlinker -stack_size -Xlinker 0x100000")
endif()
if(WITH_OPENIMAGEDENOISE)
find_package(OpenImageDenoise)
find_package(TBB)
if(NOT OPENIMAGEDENOISE_FOUND)
set(WITH_OPENIMAGEDENOISE OFF)
message(STATUS "OpenImageDenoise not found")
elseif(NOT TBB_FOUND)
set(WITH_OPENIMAGEDENOISE OFF)
message(STATUS "TBB not found")
endif()
endif()
# CMake FindOpenMP doesn't know about AppleClang before 3.12, so provide custom flags.
if(WITH_OPENMP)
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0")

@ -368,6 +368,15 @@ if(WITH_CYCLES_EMBREE)
find_package(Embree 3.2.4 REQUIRED)
endif()
if(WITH_OPENIMAGEDENOISE)
find_package_wrapper(OpenImageDenoise)
if(NOT OPENIMAGEDENOISE_FOUND)
set(WITH_OPENIMAGEDENOISE OFF)
message(STATUS "OpenImageDenoise not found")
endif()
endif()
if(WITH_LLVM)
if(EXISTS ${LIBDIR})
set(LLVM_STATIC ON)

@ -484,6 +484,19 @@ if(WITH_OPENVDB)
set(OPENVDB_DEFINITIONS -DNOMINMAX)
endif()
if(WITH_OPENIMAGEDENOISE)
set(TBB_LIBRARIES optimized ${LIBDIR}/tbb/lib/tbb.lib debug ${LIBDIR}/tbb/lib/tbb_debug.lib)
set(TBB_INCLUDE_DIR ${LIBDIR}/tbb/include)
set(OPENIMAGEDENOISE ${LIBDIR}/OpenImageDenoise)
set(OPENIMAGEDENOISE_LIBPATH ${LIBDIR}/OpenImageDenoise/lib)
set(OPENIMAGEDENOISE_INCLUDE_DIRS ${OPENIMAGEDENOISE}/include ${TBB_INCLUDE_DIR})
set(OPENIMAGEDENOISE_LIBRARIES
optimized ${OPENIMAGEDENOISE_LIBPATH}/OpenImageDenoise.lib ${OPENIMAGEDENOISE_LIBPATH}/common.lib ${OPENIMAGEDENOISE_LIBPATH}/mkldnn.lib
debug ${OPENIMAGEDENOISE_LIBPATH}/OpenImageDenoise_d.lib ${OPENIMAGEDENOISE_LIBPATH}/common_d.lib ${OPENIMAGEDENOISE_LIBPATH}/mkldnn_d.lib
${TBB_LIBRARIES})
set(OPENIMAGEDENOISE_DEFINITIONS)
endif()
if(WITH_ALEMBIC)
set(ALEMBIC ${LIBDIR}/alembic)
set(ALEMBIC_INCLUDE_DIR ${ALEMBIC}/include)

@ -352,6 +352,7 @@ compositor_node_categories = [
NodeItem("CompositorNodeDBlur"),
NodeItem("CompositorNodePixelate"),
NodeItem("CompositorNodeSunBeams"),
NodeItem("CompositorNodeDenoise"),
]),
CompositorNodeCategory("CMP_OP_VECTOR", "Vector", items=[
NodeItem("CompositorNodeNormal"),

@ -1129,6 +1129,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *localtree,
#define CMP_NODE_CORNERPIN 321
#define CMP_NODE_SWITCH_VIEW 322
#define CMP_NODE_CRYPTOMATTE 323
#define CMP_NODE_DENOISE 324
/* channel toggles */
#define CMP_CHAN_RGB 1

@ -3779,6 +3779,7 @@ static void registerCompositNodes(void)
register_node_type_cmp_despeckle();
register_node_type_cmp_defocus();
register_node_type_cmp_sunbeams();
register_node_type_cmp_denoise();
register_node_type_cmp_valtorgb();
register_node_type_cmp_rgbtobw();

@ -276,11 +276,12 @@ set(SRC
nodes/COM_VectorBlurNode.h
operations/COM_VectorBlurOperation.cpp
operations/COM_VectorBlurOperation.h
nodes/COM_BlurNode.cpp
nodes/COM_BlurNode.h
nodes/COM_BokehBlurNode.cpp
nodes/COM_BokehBlurNode.h
nodes/COM_DenoiseNode.h
nodes/COM_DenoiseNode.cpp
nodes/COM_DespeckleNode.cpp
nodes/COM_DespeckleNode.h
nodes/COM_DilateErodeNode.cpp
@ -490,6 +491,8 @@ set(SRC
operations/COM_ConvolutionEdgeFilterOperation.h
operations/COM_ConvolutionFilterOperation.cpp
operations/COM_ConvolutionFilterOperation.h
operations/COM_DenoiseOperation.h
operations/COM_DenoiseOperation.cpp
operations/COM_DespeckleOperation.cpp
operations/COM_DespeckleOperation.h
operations/COM_DilateErodeOperation.cpp
@ -558,4 +561,12 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
if(WITH_OPENIMAGEDENOISE)
add_definitions(-DWITH_OPENIMAGEDENOISE)
add_definitions(-DOIDN_STATIC_LIB)
list(APPEND INC_SYS
${OPENIMAGEDENOISE_INCLUDE_DIRS}
)
endif()
blender_add_lib(bf_compositor "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")

@ -53,6 +53,7 @@ extern "C" {
#include "COM_CropNode.h"
#include "COM_CryptomatteNode.h"
#include "COM_DefocusNode.h"
#include "COM_DenoiseNode.h"
#include "COM_DespeckleNode.h"
#include "COM_DifferenceMatteNode.h"
#include "COM_DilateErodeNode.h"
@ -122,7 +123,7 @@ bool Converter::is_fast_node(bNode *b_node)
b_node->type == CMP_NODE_BOKEHBLUR || b_node->type == CMP_NODE_GLARE ||
b_node->type == CMP_NODE_DBLUR || b_node->type == CMP_NODE_MOVIEDISTORTION ||
b_node->type == CMP_NODE_LENSDIST || b_node->type == CMP_NODE_DOUBLEEDGEMASK ||
b_node->type == CMP_NODE_DILATEERODE);
b_node->type == CMP_NODE_DILATEERODE || b_node->type == CMP_NODE_DENOISE);
}
Node *Converter::convert(bNode *b_node)
@ -402,6 +403,9 @@ Node *Converter::convert(bNode *b_node)
case CMP_NODE_CRYPTOMATTE:
node = new CryptomatteNode(b_node);
break;
case CMP_NODE_DENOISE:
node = new DenoiseNode(b_node);
break;
}
return node;
}

@ -0,0 +1,47 @@
/*
* 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_DenoiseNode.h"
#include "DNA_node_types.h"
#include "COM_SetValueOperation.h"
#include "COM_MixOperation.h"
#include "COM_DenoiseOperation.h"
DenoiseNode::DenoiseNode(bNode *editorNode) : Node(editorNode)
{
/* pass */
}
void DenoiseNode::convertToOperations(NodeConverter &converter,
const CompositorContext & /*context*/) const
{
bNode *node = this->getbNode();
NodeDenoise *denoise = (NodeDenoise *)node->storage;
DenoiseOperation *operation = new DenoiseOperation();
converter.addOperation(operation);
operation->setDenoiseSettings(denoise);
converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(2));
converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}

@ -0,0 +1,37 @@
/*
* 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_DENOISENODE_H__
#define __COM_DENOISENODE_H__
#include "COM_Node.h"
/**
* \brief DenoiseNode
* \ingroup Node
*/
class DenoiseNode : public Node {
public:
DenoiseNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif

@ -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
}

@ -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

@ -71,6 +71,10 @@ if(WITH_COMPOSITOR)
add_definitions(-DWITH_COMPOSITOR)
endif()
if(WITH_OPENIMAGEDENOISE)
add_definitions(-DWITH_OPENIMAGEDENOISE)
endif()
add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_space_node "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")

@ -2691,6 +2691,15 @@ static void node_composit_buts_brightcontrast(uiLayout *layout,
uiItemR(layout, ptr, "use_premultiply", 0, NULL, ICON_NONE);
}
static void node_composit_buts_denoise(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
#ifndef WITH_OPENIMAGEDENOISE
uiItemL(layout, IFACE_("Disabled, built without OpenImageDenoise"), ICON_ERROR);
#endif
uiItemR(layout, ptr, "use_hdr", 0, NULL, ICON_NONE);
}
/* only once called */
static void node_composit_set_butfunc(bNodeType *ntype)
{
@ -2924,6 +2933,10 @@ static void node_composit_set_butfunc(bNodeType *ntype)
break;
case CMP_NODE_BRIGHTCONTRAST:
ntype->draw_buttons = node_composit_buts_brightcontrast;
break;
case CMP_NODE_DENOISE:
ntype->draw_buttons = node_composit_buts_denoise;
break;
}
}

@ -1012,6 +1012,11 @@ typedef struct NodeCryptomatte {
char _pad[4];
} NodeCryptomatte;
typedef struct NodeDenoise {
char hdr;
char _pad[7];
} NodeDenoise;
/* script node mode */
#define NODE_SCRIPT_INTERNAL 0
#define NODE_SCRIPT_EXTERNAL 1

@ -7600,6 +7600,18 @@ static void def_cmp_cryptomatte(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeCryptomatte_update_remove");
}
static void def_cmp_denoise(StructRNA *srna)
{
PropertyRNA *prop;
RNA_def_struct_sdna_from(srna, "NodeDenoise", "storage");
prop = RNA_def_property(srna, "use_hdr", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "hdr", 0);
RNA_def_property_ui_text(prop, "HDR", "Process HDR images");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
/* -- Texture Nodes --------------------------------------------------------- */
static void def_tex_output(StructRNA *srna)

@ -62,6 +62,7 @@ set(SRC
composite/nodes/node_composite_cryptomatte.c
composite/nodes/node_composite_curves.c
composite/nodes/node_composite_defocus.c
composite/nodes/node_composite_denoise.c
composite/nodes/node_composite_despeckle.c
composite/nodes/node_composite_diffMatte.c
composite/nodes/node_composite_dilate.c

@ -74,6 +74,7 @@ void register_node_type_cmp_dilateerode(void);
void register_node_type_cmp_inpaint(void);
void register_node_type_cmp_despeckle(void);
void register_node_type_cmp_defocus(void);
void register_node_type_cmp_denoise(void);
void register_node_type_cmp_valtorgb(void);
void register_node_type_cmp_rgbtobw(void);

@ -216,6 +216,7 @@ DefNode(CompositorNode, CMP_NODE_PLANETRACKDEFORM,def_cmp_planetrackdeform,"PLAN
DefNode(CompositorNode, CMP_NODE_CORNERPIN, 0, "CORNERPIN", CornerPin, "Corner Pin", "" )
DefNode(CompositorNode, CMP_NODE_SUNBEAMS, def_cmp_sunbeams, "SUNBEAMS", SunBeams, "Sun Beams", "" )
DefNode(CompositorNode, CMP_NODE_CRYPTOMATTE, def_cmp_cryptomatte, "CRYPTOMATTE", Cryptomatte, "Cryptomatte", "" )
DefNode(CompositorNode, CMP_NODE_DENOISE, def_cmp_denoise, "DENOISE", Denoise, "Denoise", "" )
DefNode(TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" )
DefNode(TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" )

@ -0,0 +1,58 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* 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.
*
* The Original Code is Copyright (C) 2019 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Stefan Werner
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/nodes/composite/nodes/node_composite_denoise.c
* \ingroup cmpnodes
*/
#include "node_composite_util.h"
static bNodeSocketTemplate cmp_node_denoise_in[] = {
{SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f},
{SOCK_RGBA, 1, N_("Albedo"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f},
{SOCK_VECTOR, 0, N_("Normal"), 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f},
{-1, 0, ""}};
static bNodeSocketTemplate cmp_node_denoise_out[] = {{SOCK_RGBA, 0, N_("Image")}, {-1, 0, ""}};
static void node_composit_init_denonise(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeDenoise *ndg = MEM_callocN(sizeof(NodeDenoise), "node denoise data");
ndg->hdr = true;
node->storage = ndg;
}
void register_node_type_cmp_denoise(void)
{
static bNodeType ntype;
cmp_node_type_base(&ntype, CMP_NODE_DENOISE, "Denoise", NODE_CLASS_OP_FILTER, 0);
node_type_socket_templates(&ntype, cmp_node_denoise_in, cmp_node_denoise_out);
node_type_init(&ntype, node_composit_init_denonise);
node_type_storage(&ntype, "NodeDenoise", node_free_standard_storage, node_copy_standard_storage);
nodeRegisterType(&ntype);
}