diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
index 8288e796029..5d0c41698f8 100644
--- a/COPYRIGHT.txt
+++ b/COPYRIGHT.txt
@@ -63,6 +63,13 @@ Copyright: 2011, Ole Kniemeyer, MAXON, www.maxon.net
2007-2014, Juan Linietsky, Ariel Manzur
License: Expat and Zlib
+Files: ./modules/lightmapper_rd/lm_compute.glsl
+Comment: Joint Non-Local Means (JNLM) denoiser
+Copyright: 2020, Manuel Prandini
+ 2014-present, Godot Engine contributors
+ 2007-2014, Juan Linietsky, Ariel Manzur
+License: Expat
+
Files: ./platform/android/java/lib/aidl/com/android/*
./platform/android/java/lib/res/layout/status_bar_ongoing_event_progress_bar.xml
./platform/android/java/lib/src/com/google/android/*
@@ -428,11 +435,6 @@ Comment: Stripped down version of "nvapi.h" from the NVIDIA NVAPI SDK
Copyright: 2019-2022, NVIDIA Corporation
License: Expat
-Files: ./thirdparty/oidn/
-Comment: Intel Open Image Denoise
-Copyright: 2009-2019, Intel Corporation
-License: Apache-2.0
-
Files: ./thirdparty/openxr/
Comment: OpenXR Loader
Copyright: 2020-2023, The Khronos Group Inc.
diff --git a/doc/classes/LightmapGI.xml b/doc/classes/LightmapGI.xml
index 2b2fca7d356..5a050eb2566 100644
--- a/doc/classes/LightmapGI.xml
+++ b/doc/classes/LightmapGI.xml
@@ -24,6 +24,9 @@
The [CameraAttributes] resource that specifies exposure levels to bake at. Auto-exposure and non exposure properties will be ignored. Exposure settings should be used to reduce the dynamic range present when baking. If exposure is too high, the [LightmapGI] will have banding artifacts or may have over-exposure artifacts.
+
+ The strength of denoising step applied to the generated lightmaps. Only effective if [member use_denoiser] is [code]true[/code].
+
If [code]true[/code], bakes lightmaps to contain directional information as spherical harmonics. This results in more realistic lighting appearance, especially with normal mapped materials and for lights that have their direct light baked ([member Light3D.light_bake_mode] set to [constant Light3D.BAKE_STATIC]). The directional information is also used to provide rough reflections for static and dynamic objects. This has a small run-time performance cost as the shader has to perform more work to interpret the direction information from the lightmap. Directional lightmaps also take longer to bake and result in larger file sizes.
[b]Note:[/b] The property's name has no relationship with [DirectionalLight3D]. [member directional] works with all light types.
@@ -59,8 +62,7 @@
To further speed up bake times, decrease [member bounces], disable [member use_denoiser] and increase the lightmap texel size on 3D scenes in the Import doc.
- If [code]true[/code], uses a CPU-based denoising algorithm on the generated lightmap. This eliminates most noise within the generated lightmap at the cost of longer bake times. File sizes are generally not impacted significantly by the use of a denoiser, although lossless compression may do a better job at compressing a denoised image.
- [b]Note:[/b] The built-in denoiser (OpenImageDenoise) may crash when denoising lightmaps in large scenes. If you encounter a crash at the end of lightmap baking, try disabling [member use_denoiser].
+ If [code]true[/code], uses a GPU-based denoising algorithm on the generated lightmap. This eliminates most noise within the generated lightmap at the cost of longer bake times. File sizes are generally not impacted significantly by the use of a denoiser, although lossless compression may do a better job at compressing a denoised image.
diff --git a/modules/denoise/SCsub b/modules/denoise/SCsub
deleted file mode 100644
index 967a511e1e0..00000000000
--- a/modules/denoise/SCsub
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/usr/bin/env python
-
-import resource_to_cpp
-
-Import("env")
-Import("env_modules")
-
-env_oidn = env_modules.Clone()
-
-# Thirdparty source files
-
-thirdparty_obj = []
-
-thirdparty_dir = "#thirdparty/oidn/"
-thirdparty_sources = [
- "core/api.cpp",
- "core/device.cpp",
- "core/filter.cpp",
- "core/network.cpp",
- "core/autoencoder.cpp",
- "core/transfer_function.cpp",
- "weights/rtlightmap_hdr.gen.cpp",
- "mkl-dnn/src/common/batch_normalization.cpp",
- "mkl-dnn/src/common/concat.cpp",
- "mkl-dnn/src/common/convolution.cpp",
- "mkl-dnn/src/common/convolution_pd.cpp",
- "mkl-dnn/src/common/deconvolution.cpp",
- "mkl-dnn/src/common/eltwise.cpp",
- "mkl-dnn/src/common/engine.cpp",
- "mkl-dnn/src/common/inner_product.cpp",
- "mkl-dnn/src/common/inner_product_pd.cpp",
- "mkl-dnn/src/common/lrn.cpp",
- "mkl-dnn/src/common/memory.cpp",
- "mkl-dnn/src/common/memory_desc_wrapper.cpp",
- "mkl-dnn/src/common/mkldnn_debug.cpp",
- "mkl-dnn/src/common/mkldnn_debug_autogenerated.cpp",
- "mkl-dnn/src/common/pooling.cpp",
- "mkl-dnn/src/common/primitive.cpp",
- "mkl-dnn/src/common/primitive_attr.cpp",
- "mkl-dnn/src/common/primitive_desc.cpp",
- "mkl-dnn/src/common/primitive_exec_types.cpp",
- "mkl-dnn/src/common/primitive_iterator.cpp",
- "mkl-dnn/src/common/query.cpp",
- "mkl-dnn/src/common/reorder.cpp",
- "mkl-dnn/src/common/rnn.cpp",
- "mkl-dnn/src/common/scratchpad.cpp",
- "mkl-dnn/src/common/shuffle.cpp",
- "mkl-dnn/src/common/softmax.cpp",
- "mkl-dnn/src/common/stream.cpp",
- "mkl-dnn/src/common/sum.cpp",
- "mkl-dnn/src/common/utils.cpp",
- "mkl-dnn/src/common/verbose.cpp",
- "mkl-dnn/src/cpu/cpu_barrier.cpp",
- "mkl-dnn/src/cpu/cpu_concat.cpp",
- "mkl-dnn/src/cpu/cpu_engine.cpp",
- "mkl-dnn/src/cpu/cpu_memory.cpp",
- "mkl-dnn/src/cpu/cpu_reducer.cpp",
- "mkl-dnn/src/cpu/cpu_reorder.cpp",
- "mkl-dnn/src/cpu/cpu_sum.cpp",
- "mkl-dnn/src/cpu/jit_avx2_conv_kernel_f32.cpp",
- "mkl-dnn/src/cpu/jit_avx2_convolution.cpp",
- "mkl-dnn/src/cpu/jit_avx512_common_conv_kernel.cpp",
- "mkl-dnn/src/cpu/jit_avx512_common_conv_winograd_kernel_f32.cpp",
- "mkl-dnn/src/cpu/jit_avx512_common_convolution.cpp",
- "mkl-dnn/src/cpu/jit_avx512_common_convolution_winograd.cpp",
- "mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_2x3.cpp",
- "mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3.cpp",
- "mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3_kernel.cpp",
- "mkl-dnn/src/cpu/jit_sse42_conv_kernel_f32.cpp",
- "mkl-dnn/src/cpu/jit_sse42_convolution.cpp",
- "mkl-dnn/src/cpu/jit_transpose_src_utils.cpp",
- "mkl-dnn/src/cpu/jit_uni_eltwise.cpp",
- "mkl-dnn/src/cpu/jit_uni_pool_kernel_f32.cpp",
- "mkl-dnn/src/cpu/jit_uni_pooling.cpp",
- "mkl-dnn/src/cpu/jit_uni_reorder.cpp",
- "mkl-dnn/src/cpu/jit_uni_reorder_utils.cpp",
- "mkl-dnn/src/cpu/jit_utils/jit_utils.cpp",
- "mkl-dnn/src/cpu/jit_utils/jitprofiling/jitprofiling.c",
- "common/platform.cpp",
- "common/thread.cpp",
- "common/tensor.cpp",
-]
-thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
-
-thirdparty_include_dirs = [
- "",
- "include",
- "mkl-dnn/include",
- "mkl-dnn/src",
- "mkl-dnn/src/common",
- "mkl-dnn/src/cpu/xbyak",
- "mkl-dnn/src/cpu",
-]
-thirdparty_include_dirs = [thirdparty_dir + file for file in thirdparty_include_dirs]
-
-
-env_oidn.Prepend(CPPPATH=thirdparty_include_dirs)
-env_oidn.Append(
- CPPDEFINES=[
- "MKLDNN_THR=MKLDNN_THR_SEQ",
- "OIDN_STATIC_LIB",
- "__STDC_CONSTANT_MACROS",
- "__STDC_LIMIT_MACROS",
- "DISABLE_VERBOSE",
- "MKLDNN_ENABLE_CONCURRENT_EXEC",
- ]
-)
-env_oidn.AppendUnique(CPPDEFINES=["NDEBUG"]) # No assert() even in debug builds.
-
-env_thirdparty = env_oidn.Clone()
-env_thirdparty.disable_warnings()
-
-if env["disable_exceptions"]:
- # OIDN hard-requires exceptions, so we re-enable them here.
- if env.msvc and ("_HAS_EXCEPTIONS", 0) in env_thirdparty["CPPDEFINES"]:
- env_thirdparty["CPPDEFINES"].remove(("_HAS_EXCEPTIONS", 0))
- env_thirdparty.AppendUnique(CCFLAGS=["/EHsc"])
- elif not env.msvc and "-fno-exceptions" in env_thirdparty["CCFLAGS"]:
- env_thirdparty["CCFLAGS"].remove("-fno-exceptions")
-
-env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
-env.modules_sources += thirdparty_obj
-
-weights_in_path = thirdparty_dir + "weights/rtlightmap_hdr.tza"
-weights_out_path = thirdparty_dir + "weights/rtlightmap_hdr.gen.cpp"
-
-env_thirdparty.Depends(weights_out_path, weights_in_path)
-env_thirdparty.CommandNoCache(weights_out_path, weights_in_path, resource_to_cpp.tza_to_cpp)
-
-# Godot source files
-
-module_obj = []
-
-env_oidn.add_source_files(module_obj, "*.cpp")
-env.modules_sources += module_obj
-
-# Needed to force rebuilding the module files when the thirdparty library is updated.
-env.Depends(module_obj, thirdparty_obj)
diff --git a/modules/denoise/config.py b/modules/denoise/config.py
deleted file mode 100644
index 27d2ffbf864..00000000000
--- a/modules/denoise/config.py
+++ /dev/null
@@ -1,12 +0,0 @@
-def can_build(env, platform):
- # Thirdparty dependency OpenImage Denoise includes oneDNN library
- # and the version we use only supports x86_64.
- # It's also only relevant for tools build and desktop platforms,
- # as doing lightmap generation and denoising on Android or Web
- # would be a bit far-fetched.
- desktop_platforms = ["linuxbsd", "macos", "windows"]
- return env.editor_build and platform in desktop_platforms and env["arch"] == "x86_64"
-
-
-def configure(env):
- pass
diff --git a/modules/denoise/denoise_wrapper.cpp b/modules/denoise/denoise_wrapper.cpp
deleted file mode 100644
index 87f02cb4c6c..00000000000
--- a/modules/denoise/denoise_wrapper.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/**************************************************************************/
-/* denoise_wrapper.cpp */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#include "denoise_wrapper.h"
-
-#include
-
-#include
-
-void *oidn_denoiser_init() {
- OIDNDeviceImpl *device = oidnNewDevice(OIDN_DEVICE_TYPE_CPU);
- oidnCommitDevice(device);
- return device;
-}
-
-bool oidn_denoise(void *deviceptr, float *p_floats, int p_width, int p_height) {
- OIDNDeviceImpl *device = (OIDNDeviceImpl *)deviceptr;
- OIDNFilter filter = oidnNewFilter(device, "RTLightmap");
- oidnSetSharedFilterImage(filter, "color", (void *)p_floats, OIDN_FORMAT_FLOAT3, p_width, p_height, 0, 0, 0);
- oidnSetSharedFilterImage(filter, "output", (void *)p_floats, OIDN_FORMAT_FLOAT3, p_width, p_height, 0, 0, 0);
- oidnSetFilter1b(filter, "hdr", true);
- //oidnSetFilter1f(filter, "hdrScale", 1.0f);
- oidnCommitFilter(filter);
- oidnExecuteFilter(filter);
-
- const char *msg;
- bool success = true;
- if (oidnGetDeviceError(device, &msg) != OIDN_ERROR_NONE) {
- printf("LightmapDenoiser: %s\n", msg);
- success = false;
- }
-
- oidnReleaseFilter(filter);
- return success;
-}
-
-void oidn_denoiser_finish(void *device) {
- oidnReleaseDevice((OIDNDeviceImpl *)device);
-}
diff --git a/modules/denoise/denoise_wrapper.h b/modules/denoise/denoise_wrapper.h
deleted file mode 100644
index d4bf154a5d4..00000000000
--- a/modules/denoise/denoise_wrapper.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/**************************************************************************/
-/* denoise_wrapper.h */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#ifndef DENOISE_WRAPPER_H
-#define DENOISE_WRAPPER_H
-
-void *oidn_denoiser_init();
-bool oidn_denoise(void *device, float *p_floats, int p_width, int p_height);
-void oidn_denoiser_finish(void *device);
-
-#endif // DENOISE_WRAPPER_H
diff --git a/modules/denoise/lightmap_denoiser.cpp b/modules/denoise/lightmap_denoiser.cpp
deleted file mode 100644
index 72764036e12..00000000000
--- a/modules/denoise/lightmap_denoiser.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/**************************************************************************/
-/* lightmap_denoiser.cpp */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#include "lightmap_denoiser.h"
-
-#include "denoise_wrapper.h"
-
-#include "core/io/image.h"
-
-LightmapDenoiser *LightmapDenoiserOIDN::create_oidn_denoiser() {
- return memnew(LightmapDenoiserOIDN);
-}
-
-void LightmapDenoiserOIDN::make_default_denoiser() {
- create_function = create_oidn_denoiser;
-}
-
-Ref LightmapDenoiserOIDN::denoise_image(const Ref &p_image) {
- Ref img = p_image->duplicate();
-
- img->convert(Image::FORMAT_RGBF);
-
- Vector data = img->get_data();
- if (!oidn_denoise(device, (float *)data.ptrw(), img->get_width(), img->get_height())) {
- return p_image;
- }
-
- img->set_data(img->get_width(), img->get_height(), false, img->get_format(), data);
- return img;
-}
-
-LightmapDenoiserOIDN::LightmapDenoiserOIDN() {
- device = oidn_denoiser_init();
-}
-
-LightmapDenoiserOIDN::~LightmapDenoiserOIDN() {
- oidn_denoiser_finish(device);
-}
diff --git a/modules/denoise/lightmap_denoiser.h b/modules/denoise/lightmap_denoiser.h
deleted file mode 100644
index 8f658ab0969..00000000000
--- a/modules/denoise/lightmap_denoiser.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/**************************************************************************/
-/* lightmap_denoiser.h */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#ifndef LIGHTMAP_DENOISER_H
-#define LIGHTMAP_DENOISER_H
-
-#include "core/object/class_db.h"
-#include "scene/3d/lightmapper.h"
-
-struct OIDNDeviceImpl;
-
-class LightmapDenoiserOIDN : public LightmapDenoiser {
- GDCLASS(LightmapDenoiserOIDN, LightmapDenoiser);
-
-protected:
- void *device = nullptr;
-
-public:
- static LightmapDenoiser *create_oidn_denoiser();
-
- Ref denoise_image(const Ref &p_image) override;
-
- static void make_default_denoiser();
-
- LightmapDenoiserOIDN();
- ~LightmapDenoiserOIDN();
-};
-
-#endif // LIGHTMAP_DENOISER_H
diff --git a/modules/denoise/register_types.cpp b/modules/denoise/register_types.cpp
deleted file mode 100644
index a4264b07c53..00000000000
--- a/modules/denoise/register_types.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/**************************************************************************/
-/* register_types.cpp */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#include "register_types.h"
-
-#include "lightmap_denoiser.h"
-
-#include "core/config/engine.h"
-
-void initialize_denoise_module(ModuleInitializationLevel p_level) {
- if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
- return;
- }
-
- LightmapDenoiserOIDN::make_default_denoiser();
-}
-
-void uninitialize_denoise_module(ModuleInitializationLevel p_level) {
- if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
- return;
- }
-}
diff --git a/modules/denoise/register_types.h b/modules/denoise/register_types.h
deleted file mode 100644
index 239877a5c7d..00000000000
--- a/modules/denoise/register_types.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/**************************************************************************/
-/* register_types.h */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#ifndef DENOISE_REGISTER_TYPES_H
-#define DENOISE_REGISTER_TYPES_H
-
-#include "modules/register_module_types.h"
-
-void initialize_denoise_module(ModuleInitializationLevel p_level);
-void uninitialize_denoise_module(ModuleInitializationLevel p_level);
-
-#endif // DENOISE_REGISTER_TYPES_H
diff --git a/modules/denoise/resource_to_cpp.py b/modules/denoise/resource_to_cpp.py
deleted file mode 100644
index a89eda91175..00000000000
--- a/modules/denoise/resource_to_cpp.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env python
-
-## ======================================================================== ##
-## Copyright 2009-2019 Intel Corporation ##
-## ##
-## Licensed under the Apache License, Version 2.0 (the "License"); ##
-## you may not use this file except in compliance with the License. ##
-## You may obtain a copy of the License at ##
-## ##
-## http://www.apache.org/licenses/LICENSE-2.0 ##
-## ##
-## Unless required by applicable law or agreed to in writing, software ##
-## distributed under the License is distributed on an "AS IS" BASIS, ##
-## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ##
-## See the License for the specific language governing permissions and ##
-## limitations under the License. ##
-## ======================================================================== ##
-
-import os
-from array import array
-
-
-# Generates a C++ file from the specified binary resource file
-def generate(in_path, out_path):
- namespace = "oidn::weights"
- scopes = namespace.split("::")
-
- file_name = os.path.basename(in_path)
- var_name = os.path.splitext(file_name)[0]
-
- with open(in_path, "rb") as in_file, open(out_path, "w") as out_file:
- # Header
- out_file.write("// Generated from: %s\n" % file_name)
- out_file.write("#include \n\n")
-
- # Open the namespaces
- for s in scopes:
- out_file.write("namespace %s {\n" % s)
- if scopes:
- out_file.write("\n")
-
- # Read the file
- in_data = array("B", in_file.read())
-
- # Write the size
- out_file.write("//const size_t %s_size = %d;\n\n" % (var_name, len(in_data)))
-
- # Write the data
- out_file.write("unsigned char %s[] = {" % var_name)
- for i in range(len(in_data)):
- c = in_data[i]
- if i > 0:
- out_file.write(",")
- if (i + 1) % 20 == 1:
- out_file.write("\n")
- out_file.write("%d" % c)
- out_file.write("\n};\n")
-
- # Close the namespaces
- if scopes:
- out_file.write("\n")
- for scope in reversed(scopes):
- out_file.write("} // namespace %s\n" % scope)
-
-
-def tza_to_cpp(target, source, env):
- for x in zip(source, target):
- generate(str(x[0]), str(x[1]))
diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp
index 4ed730b3af7..e9550f9c28c 100644
--- a/modules/lightmapper_rd/lightmapper_rd.cpp
+++ b/modules/lightmapper_rd/lightmapper_rd.cpp
@@ -614,24 +614,28 @@ void LightmapperRD::_raster_geometry(RenderingDevice *rd, Size2i atlas_size, int
}
}
-LightmapperRD::BakeError LightmapperRD::_dilate(RenderingDevice *rd, Ref &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices) {
+static Vector dilate_or_denoise_common_uniforms(RID &p_source_light_tex, RID &p_dest_light_tex) {
Vector uniforms;
{
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 0;
- u.append_id(dest_light_tex);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1;
- u.append_id(source_light_tex);
- uniforms.push_back(u);
- }
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 0;
+ u.append_id(p_dest_light_tex);
+ uniforms.push_back(u);
}
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 1;
+ u.append_id(p_source_light_tex);
+ uniforms.push_back(u);
+ }
+
+ return uniforms;
+}
+
+LightmapperRD::BakeError LightmapperRD::_dilate(RenderingDevice *rd, Ref &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices) {
+ Vector uniforms = dilate_or_denoise_common_uniforms(source_light_tex, dest_light_tex);
RID compute_shader_dilate = rd->shader_create_from_spirv(compute_shader->get_spirv_stages("dilate"));
ERR_FAIL_COND_V(compute_shader_dilate.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen
@@ -667,7 +671,77 @@ LightmapperRD::BakeError LightmapperRD::_dilate(RenderingDevice *rd, Ref &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function, void *p_bake_userdata, float p_exposure_normalization) {
+LightmapperRD::BakeError LightmapperRD::_denoise(RenderingDevice *p_rd, Ref &p_compute_shader, const RID &p_compute_base_uniform_set, PushConstant &p_push_constant, RID p_source_light_tex, RID p_source_normal_tex, RID p_dest_light_tex, float p_denoiser_strength, const Size2i &p_atlas_size, int p_atlas_slices, bool p_bake_sh, BakeStepFunc p_step_function) {
+ RID denoise_params_buffer = p_rd->uniform_buffer_create(sizeof(DenoiseParams));
+ DenoiseParams denoise_params;
+ denoise_params.spatial_bandwidth = 5.0f;
+ denoise_params.light_bandwidth = p_denoiser_strength;
+ denoise_params.albedo_bandwidth = 1.0f;
+ denoise_params.normal_bandwidth = 0.1f;
+ denoise_params.filter_strength = 10.0f;
+ p_rd->buffer_update(denoise_params_buffer, 0, sizeof(DenoiseParams), &denoise_params);
+
+ Vector uniforms = dilate_or_denoise_common_uniforms(p_source_light_tex, p_dest_light_tex);
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 2;
+ u.append_id(p_source_normal_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 3;
+ u.append_id(denoise_params_buffer);
+ uniforms.push_back(u);
+ }
+
+ RID compute_shader_denoise = p_rd->shader_create_from_spirv(p_compute_shader->get_spirv_stages("denoise"));
+ ERR_FAIL_COND_V(compute_shader_denoise.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES);
+
+ RID compute_shader_denoise_pipeline = p_rd->compute_pipeline_create(compute_shader_denoise);
+ RID denoise_uniform_set = p_rd->uniform_set_create(uniforms, compute_shader_denoise, 1);
+
+ // We denoise in fixed size regions and synchronize execution to avoid GPU timeouts.
+ // We use a region with 1/4 the amount of pixels if we're denoising SH lightmaps, as
+ // all four of them are denoised in the shader in one dispatch.
+ const int max_region_size = p_bake_sh ? 512 : 1024;
+ int x_regions = (p_atlas_size.width - 1) / max_region_size + 1;
+ int y_regions = (p_atlas_size.height - 1) / max_region_size + 1;
+ for (int s = 0; s < p_atlas_slices; s++) {
+ p_push_constant.atlas_slice = s;
+
+ for (int i = 0; i < x_regions; i++) {
+ for (int j = 0; j < y_regions; j++) {
+ int x = i * max_region_size;
+ int y = j * max_region_size;
+ int w = MIN((i + 1) * max_region_size, p_atlas_size.width) - x;
+ int h = MIN((j + 1) * max_region_size, p_atlas_size.height) - y;
+ p_push_constant.region_ofs[0] = x;
+ p_push_constant.region_ofs[1] = y;
+
+ RD::ComputeListID compute_list = p_rd->compute_list_begin();
+ p_rd->compute_list_bind_compute_pipeline(compute_list, compute_shader_denoise_pipeline);
+ p_rd->compute_list_bind_uniform_set(compute_list, p_compute_base_uniform_set, 0);
+ p_rd->compute_list_bind_uniform_set(compute_list, denoise_uniform_set, 1);
+ p_rd->compute_list_set_push_constant(compute_list, &p_push_constant, sizeof(PushConstant));
+ p_rd->compute_list_dispatch(compute_list, (w - 1) / 8 + 1, (h - 1) / 8 + 1, 1);
+ p_rd->compute_list_end();
+
+ p_rd->submit();
+ p_rd->sync();
+ }
+ }
+ }
+
+ p_rd->free(compute_shader_denoise);
+ p_rd->free(denoise_params_buffer);
+
+ return BAKE_OK;
+}
+
+LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_denoiser, float p_denoiser_strength, int p_bounces, float p_bias, int p_max_texture_size, bool p_bake_sh, GenerateProbes p_generate_probes, const Ref &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function, void *p_bake_userdata, float p_exposure_normalization) {
if (p_step_function) {
p_step_function(0.0, RTR("Begin Bake"), p_bake_userdata, true);
}
@@ -1434,27 +1508,11 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
p_step_function(0.8, RTR("Denoising"), p_bake_userdata, true);
}
- Ref denoiser = LightmapDenoiser::create();
- if (denoiser.is_valid()) {
- for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) {
- Vector s = rd->texture_get_data(light_accum_tex, i);
- Ref img = Image::create_from_data(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s);
-
- Ref denoised = denoiser->denoise_image(img);
- if (denoised != img) {
- denoised->convert(Image::FORMAT_RGBAH);
- Vector ds = denoised->get_data();
- denoised.unref(); //avoid copy on write
- { //restore alpha
- uint32_t count = s.size() / 2; //uint16s
- const uint16_t *src = (const uint16_t *)s.ptr();
- uint16_t *dst = (uint16_t *)ds.ptrw();
- for (uint32_t j = 0; j < count; j += 4) {
- dst[j + 3] = src[j + 3];
- }
- }
- rd->texture_update(light_accum_tex, i, ds);
- }
+ {
+ SWAP(light_accum_tex, light_accum_tex2);
+ BakeError error = _denoise(rd, compute_shader, compute_base_uniform_set, push_constant, light_accum_tex2, normal_tex, light_accum_tex, p_denoiser_strength, atlas_size, atlas_slices, p_bake_sh, p_step_function);
+ if (unlikely(error != BAKE_OK)) {
+ return error;
}
}
diff --git a/modules/lightmapper_rd/lightmapper_rd.h b/modules/lightmapper_rd/lightmapper_rd.h
index 061c9ba000c..7120a21b843 100644
--- a/modules/lightmapper_rd/lightmapper_rd.h
+++ b/modules/lightmapper_rd/lightmapper_rd.h
@@ -229,11 +229,22 @@ class LightmapperRD : public Lightmapper {
Vector[> bake_textures;
Vector probe_values;
+ struct DenoiseParams {
+ float spatial_bandwidth;
+ float light_bandwidth;
+ float albedo_bandwidth;
+ float normal_bandwidth;
+
+ float filter_strength;
+ float pad[3];
+ };
+
BakeError _blit_meshes_into_atlas(int p_max_texture_size, Vector][> &albedo_images, Vector][> &emission_images, AABB &bounds, Size2i &atlas_size, int &atlas_slices, BakeStepFunc p_step_function, void *p_bake_userdata);
void _create_acceleration_structures(RenderingDevice *rd, Size2i atlas_size, int atlas_slices, AABB &bounds, int grid_size, Vector &probe_positions, GenerateProbes p_generate_probes, Vector &slice_triangle_count, Vector &slice_seam_count, RID &vertex_buffer, RID &triangle_buffer, RID &lights_buffer, RID &triangle_cell_indices_buffer, RID &probe_positions_buffer, RID &grid_texture, RID &seams_buffer, BakeStepFunc p_step_function, void *p_bake_userdata);
void _raster_geometry(RenderingDevice *rd, Size2i atlas_size, int atlas_slices, int grid_size, AABB bounds, float p_bias, Vector slice_triangle_count, RID position_tex, RID unocclude_tex, RID normal_tex, RID raster_depth_buffer, RID rasterize_shader, RID raster_base_uniform);
BakeError _dilate(RenderingDevice *rd, Ref &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices);
+ BakeError _denoise(RenderingDevice *p_rd, Ref &p_compute_shader, const RID &p_compute_base_uniform_set, PushConstant &p_push_constant, RID p_source_light_tex, RID p_source_normal_tex, RID p_dest_light_tex, float p_denoiser_strength, const Size2i &p_atlas_size, int p_atlas_slices, bool p_bake_sh, BakeStepFunc p_step_function);
public:
virtual void add_mesh(const MeshData &p_mesh) override;
@@ -241,7 +252,7 @@ public:
virtual void add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_size, float p_shadow_blur) override;
virtual void add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size, float p_shadow_blur) override;
virtual void add_probe(const Vector3 &p_position) override;
- virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bias, int p_max_texture_size, bool p_bake_sh, GenerateProbes p_generate_probes, const Ref &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_bake_userdata = nullptr, float p_exposure_normalization = 1.0) override;
+ virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, float p_denoiser_strength, int p_bounces, float p_bias, int p_max_texture_size, bool p_bake_sh, GenerateProbes p_generate_probes, const Ref &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_bake_userdata = nullptr, float p_exposure_normalization = 1.0) override;
int get_bake_texture_count() const override;
Ref get_bake_texture(int p_index) const override;
diff --git a/modules/lightmapper_rd/lm_compute.glsl b/modules/lightmapper_rd/lm_compute.glsl
index 4d3f2d46a46..ce33f2ed1d8 100644
--- a/modules/lightmapper_rd/lm_compute.glsl
+++ b/modules/lightmapper_rd/lm_compute.glsl
@@ -5,6 +5,7 @@ secondary = "#define MODE_BOUNCE_LIGHT";
dilate = "#define MODE_DILATE";
unocclude = "#define MODE_UNOCCLUDE";
light_probes = "#define MODE_LIGHT_PROBES";
+denoise = "#define MODE_DENOISE";
#[compute]
@@ -65,11 +66,24 @@ layout(set = 1, binding = 6) uniform texture2D environment;
layout(rgba32f, set = 1, binding = 5) uniform restrict writeonly image2DArray primary_dynamic;
#endif
-#ifdef MODE_DILATE
+#if defined(MODE_DILATE) || defined(MODE_DENOISE)
layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly image2DArray dest_light;
layout(set = 1, binding = 1) uniform texture2DArray source_light;
#endif
+#ifdef MODE_DENOISE
+layout(set = 1, binding = 2) uniform texture2DArray source_normal;
+layout(set = 1, binding = 3) uniform DenoiseParams {
+ float spatial_bandwidth;
+ float light_bandwidth;
+ float albedo_bandwidth;
+ float normal_bandwidth;
+
+ float filter_strength;
+}
+denoise_params;
+#endif
+
layout(push_constant, std430) uniform Params {
ivec2 atlas_size; // x used for light probe mode total probes
uint ray_count;
@@ -735,4 +749,153 @@ void main() {
imageStore(dest_light, ivec3(atlas_pos, params.atlas_slice), c);
#endif
+
+#ifdef MODE_DENOISE
+ // Joint Non-local means (JNLM) denoiser.
+ //
+ // Based on YoctoImageDenoiser's JNLM implementation with corrections from "Nonlinearly Weighted First-order Regression for Denoising Monte Carlo Renderings".
+ //
+ //
+ //
+ //
+ // MIT License
+ //
+ // Copyright (c) 2020 ManuelPrandini
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
+ // of this software and associated documentation files (the "Software"), to deal
+ // in the Software without restriction, including without limitation the rights
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ // copies of the Software, and to permit persons to whom the Software is
+ // furnished to do so, subject to the following conditions:
+ //
+ // The above copyright notice and this permission notice shall be included in all
+ // copies or substantial portions of the Software.
+ //
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ // SOFTWARE.
+ //
+ // Most of the constants below have been hand-picked to fit the common scenarios lightmaps
+ // are generated with, but they can be altered freely to experiment and achieve better results.
+
+ // Half the size of the patch window around each pixel that is weighted to compute the denoised pixel.
+ // A value of 1 represents a 3x3 window, a value of 2 a 5x5 window, etc.
+ const int HALF_PATCH_WINDOW = 4;
+
+ // Half the size of the search window around each pixel that is denoised and weighted to compute the denoised pixel.
+ const int HALF_SEARCH_WINDOW = 10;
+
+ // For all of the following sigma values, smaller values will give less weight to pixels that have a bigger distance
+ // in the feature being evaluated. Therefore, smaller values are likely to cause more noise to appear, but will also
+ // cause less features to be erased in the process.
+
+ // Controls how much the spatial distance of the pixels influences the denoising weight.
+ const float SIGMA_SPATIAL = denoise_params.spatial_bandwidth;
+
+ // Controls how much the light color distance of the pixels influences the denoising weight.
+ const float SIGMA_LIGHT = denoise_params.light_bandwidth;
+
+ // Controls how much the albedo color distance of the pixels influences the denoising weight.
+ const float SIGMA_ALBEDO = denoise_params.albedo_bandwidth;
+
+ // Controls how much the normal vector distance of the pixels influences the denoising weight.
+ const float SIGMA_NORMAL = denoise_params.normal_bandwidth;
+
+ // Strength of the filter. The original paper recommends values around 10 to 15 times the Sigma parameter.
+ const float FILTER_VALUE = denoise_params.filter_strength * SIGMA_LIGHT;
+
+ // Formula constants.
+ const int PATCH_WINDOW_DIMENSION = (HALF_PATCH_WINDOW * 2 + 1);
+ const int PATCH_WINDOW_DIMENSION_SQUARE = (PATCH_WINDOW_DIMENSION * PATCH_WINDOW_DIMENSION);
+ const float TWO_SIGMA_SPATIAL_SQUARE = 2.0f * SIGMA_SPATIAL * SIGMA_SPATIAL;
+ const float TWO_SIGMA_LIGHT_SQUARE = 2.0f * SIGMA_LIGHT * SIGMA_LIGHT;
+ const float TWO_SIGMA_ALBEDO_SQUARE = 2.0f * SIGMA_ALBEDO * SIGMA_ALBEDO;
+ const float TWO_SIGMA_NORMAL_SQUARE = 2.0f * SIGMA_NORMAL * SIGMA_NORMAL;
+ const float FILTER_SQUARE_TWO_SIGMA_LIGHT_SQUARE = FILTER_VALUE * FILTER_VALUE * TWO_SIGMA_LIGHT_SQUARE;
+ const float EPSILON = 1e-6f;
+
+#ifdef USE_SH_LIGHTMAPS
+ const uint slice_count = 4;
+ const uint slice_base = params.atlas_slice * slice_count;
+#else
+ const uint slice_count = 1;
+ const uint slice_base = params.atlas_slice;
+#endif
+
+ for (uint i = 0; i < slice_count; i++) {
+ uint lightmap_slice = slice_base + i;
+ vec3 denoised_rgb = vec3(0.0f);
+ vec4 input_light = texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos, lightmap_slice), 0);
+ vec3 input_albedo = texelFetch(sampler2DArray(albedo_tex, linear_sampler), ivec3(atlas_pos, params.atlas_slice), 0).rgb;
+ vec3 input_normal = texelFetch(sampler2DArray(source_normal, linear_sampler), ivec3(atlas_pos, params.atlas_slice), 0).xyz;
+ if (length(input_normal) > EPSILON) {
+ // Compute the denoised pixel if the normal is valid.
+ float sum_weights = 0.0f;
+ vec3 input_rgb = input_light.rgb;
+ for (int search_y = -HALF_SEARCH_WINDOW; search_y <= HALF_SEARCH_WINDOW; search_y++) {
+ for (int search_x = -HALF_SEARCH_WINDOW; search_x <= HALF_SEARCH_WINDOW; search_x++) {
+ ivec2 search_pos = atlas_pos + ivec2(search_x, search_y);
+ vec3 search_rgb = texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(search_pos, lightmap_slice), 0).rgb;
+ vec3 search_albedo = texelFetch(sampler2DArray(albedo_tex, linear_sampler), ivec3(search_pos, params.atlas_slice), 0).rgb;
+ vec3 search_normal = texelFetch(sampler2DArray(source_normal, linear_sampler), ivec3(search_pos, params.atlas_slice), 0).xyz;
+ float patch_square_dist = 0.0f;
+ for (int offset_y = -HALF_PATCH_WINDOW; offset_y <= HALF_PATCH_WINDOW; offset_y++) {
+ for (int offset_x = -HALF_PATCH_WINDOW; offset_x <= HALF_PATCH_WINDOW; offset_x++) {
+ ivec2 offset_input_pos = atlas_pos + ivec2(offset_x, offset_y);
+ ivec2 offset_search_pos = search_pos + ivec2(offset_x, offset_y);
+ vec3 offset_input_rgb = texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(offset_input_pos, lightmap_slice), 0).rgb;
+ vec3 offset_search_rgb = texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(offset_search_pos, lightmap_slice), 0).rgb;
+ vec3 offset_delta_rgb = offset_input_rgb - offset_search_rgb;
+ patch_square_dist += dot(offset_delta_rgb, offset_delta_rgb) - TWO_SIGMA_LIGHT_SQUARE;
+ }
+ }
+
+ patch_square_dist = max(0.0f, patch_square_dist / (3.0f * PATCH_WINDOW_DIMENSION_SQUARE));
+
+ float weight = 1.0f;
+
+ // Ignore weight if search position is out of bounds.
+ weight *= step(0, search_pos.x) * step(search_pos.x, params.atlas_size.x - 1);
+ weight *= step(0, search_pos.y) * step(search_pos.y, params.atlas_size.y - 1);
+
+ // Ignore weight if normal is zero length.
+ weight *= step(EPSILON, length(search_normal));
+
+ // Weight with pixel distance.
+ vec2 pixel_delta = vec2(search_x, search_y);
+ float pixel_square_dist = dot(pixel_delta, pixel_delta);
+ weight *= exp(-pixel_square_dist / TWO_SIGMA_SPATIAL_SQUARE);
+
+ // Weight with patch.
+ weight *= exp(-patch_square_dist / FILTER_SQUARE_TWO_SIGMA_LIGHT_SQUARE);
+
+ // Weight with albedo.
+ vec3 albedo_delta = input_albedo - search_albedo;
+ float albedo_square_dist = dot(albedo_delta, albedo_delta);
+ weight *= exp(-albedo_square_dist / TWO_SIGMA_ALBEDO_SQUARE);
+
+ // Weight with normal.
+ vec3 normal_delta = input_normal - search_normal;
+ float normal_square_dist = dot(normal_delta, normal_delta);
+ weight *= exp(-normal_square_dist / TWO_SIGMA_NORMAL_SQUARE);
+
+ denoised_rgb += weight * search_rgb;
+ sum_weights += weight;
+ }
+ }
+
+ denoised_rgb /= sum_weights;
+ } else {
+ // Ignore pixels where the normal is empty, just copy the light color.
+ denoised_rgb = input_light.rgb;
+ }
+
+ imageStore(dest_light, ivec3(atlas_pos, lightmap_slice), vec4(denoised_rgb, input_light.a));
+ }
+#endif
}
diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp
index 3d40e9795e0..21d0b12bdbf 100644
--- a/scene/3d/lightmap_gi.cpp
+++ b/scene/3d/lightmap_gi.cpp
@@ -1080,7 +1080,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa
}
}
- Lightmapper::BakeError bake_err = lightmapper->bake(Lightmapper::BakeQuality(bake_quality), use_denoiser, bounces, bias, max_texture_size, directional, Lightmapper::GenerateProbes(gen_probes), environment_image, environment_transform, _lightmap_bake_step_function, &bsud, exposure_normalization);
+ Lightmapper::BakeError bake_err = lightmapper->bake(Lightmapper::BakeQuality(bake_quality), use_denoiser, denoiser_strength, bounces, bias, max_texture_size, directional, Lightmapper::GenerateProbes(gen_probes), environment_image, environment_transform, _lightmap_bake_step_function, &bsud, exposure_normalization);
if (bake_err == Lightmapper::BAKE_ERROR_LIGHTMAP_TOO_SMALL) {
return BAKE_ERROR_TEXTURE_SIZE_TOO_SMALL;
@@ -1362,12 +1362,21 @@ AABB LightmapGI::get_aabb() const {
void LightmapGI::set_use_denoiser(bool p_enable) {
use_denoiser = p_enable;
+ notify_property_list_changed();
}
bool LightmapGI::is_using_denoiser() const {
return use_denoiser;
}
+void LightmapGI::set_denoiser_strength(float p_denoiser_strength) {
+ denoiser_strength = p_denoiser_strength;
+}
+
+float LightmapGI::get_denoiser_strength() const {
+ return denoiser_strength;
+}
+
void LightmapGI::set_directional(bool p_enable) {
directional = p_enable;
}
@@ -1482,6 +1491,9 @@ void LightmapGI::_validate_property(PropertyInfo &p_property) const {
if (p_property.name == "environment_custom_energy" && environment_mode != ENVIRONMENT_MODE_CUSTOM_COLOR && environment_mode != ENVIRONMENT_MODE_CUSTOM_SKY) {
p_property.usage = PROPERTY_USAGE_NONE;
}
+ if (p_property.name == "denoiser_strength" && !use_denoiser) {
+ p_property.usage = PROPERTY_USAGE_NONE;
+ }
}
void LightmapGI::_bind_methods() {
@@ -1518,6 +1530,9 @@ void LightmapGI::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_denoiser", "use_denoiser"), &LightmapGI::set_use_denoiser);
ClassDB::bind_method(D_METHOD("is_using_denoiser"), &LightmapGI::is_using_denoiser);
+ ClassDB::bind_method(D_METHOD("set_denoiser_strength", "denoiser_strength"), &LightmapGI::set_denoiser_strength);
+ ClassDB::bind_method(D_METHOD("get_denoiser_strength"), &LightmapGI::get_denoiser_strength);
+
ClassDB::bind_method(D_METHOD("set_interior", "enable"), &LightmapGI::set_interior);
ClassDB::bind_method(D_METHOD("is_interior"), &LightmapGI::is_interior);
@@ -1535,6 +1550,7 @@ void LightmapGI::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "directional"), "set_directional", "is_directional");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_interior", "is_interior");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_denoiser"), "set_use_denoiser", "is_using_denoiser");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "denoiser_strength", PROPERTY_HINT_RANGE, "0.001,0.2,0.001,or_greater"), "set_denoiser_strength", "get_denoiser_strength");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bias", PROPERTY_HINT_RANGE, "0.00001,0.1,0.00001,or_greater"), "set_bias", "get_bias");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_texture_size", PROPERTY_HINT_RANGE, "2048,16384,1"), "set_max_texture_size", "get_max_texture_size");
ADD_GROUP("Environment", "environment_");
diff --git a/scene/3d/lightmap_gi.h b/scene/3d/lightmap_gi.h
index 02123ef7ba6..7059afbc7a9 100644
--- a/scene/3d/lightmap_gi.h
+++ b/scene/3d/lightmap_gi.h
@@ -145,6 +145,7 @@ public:
private:
BakeQuality bake_quality = BAKE_QUALITY_MEDIUM;
bool use_denoiser = true;
+ float denoiser_strength = 0.1f;
int bounces = 3;
float bias = 0.0005;
int max_texture_size = 16384;
@@ -239,6 +240,9 @@ public:
void set_use_denoiser(bool p_enable);
bool is_using_denoiser() const;
+ void set_denoiser_strength(float p_denoiser_strength);
+ float get_denoiser_strength() const;
+
void set_directional(bool p_enable);
bool is_directional() const;
diff --git a/scene/3d/lightmapper.h b/scene/3d/lightmapper.h
index 5a390eaede2..3400a6c59a1 100644
--- a/scene/3d/lightmapper.h
+++ b/scene/3d/lightmapper.h
@@ -180,7 +180,7 @@ public:
virtual void add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_size, float p_shadow_blur) = 0;
virtual void add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size, float p_shadow_blur) = 0;
virtual void add_probe(const Vector3 &p_position) = 0;
- virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bias, int p_max_texture_size, bool p_bake_sh, GenerateProbes p_generate_probes, const Ref &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_step_userdata = nullptr, float p_exposure_normalization = 1.0) = 0;
+ virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, float p_denoiser_strength, int p_bounces, float p_bias, int p_max_texture_size, bool p_bake_sh, GenerateProbes p_generate_probes, const Ref &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_step_userdata = nullptr, float p_exposure_normalization = 1.0) = 0;
virtual int get_bake_texture_count() const = 0;
virtual Ref get_bake_texture(int p_index) const = 0;
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 15d9ad4e8e5..9fc9106170c 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -650,37 +650,6 @@ Files extracted from the upstream source:
- `nvapi_minimal.h` was created by using `nvapi.h` from upstream and removing unnecessary code.
-## oidn
-
-- Upstream: https://github.com/OpenImageDenoise/oidn
-- Version: 1.1.0 (c58c5216db05ceef4cde5a096862f2eeffd14c06, 2019)
-- License: Apache 2.0
-
-Files extracted from upstream source:
-
-- common/* (except tasking.* and CMakeLists.txt)
-- core/*
-- include/OpenImageDenoise/* (except version.h.in)
-- LICENSE.txt
-- mkl-dnn/include/*
-- mkl-dnn/src/* (except CMakeLists.txt)
-- weights/rtlightmap_hdr.tza
-- scripts/resource_to_cpp.py
-
-Modified files:
-Modifications are marked with `// -- GODOT start --` and `// -- GODOT end --`.
-Patch files are provided in `oidn/patches/`.
-
-- core/autoencoder.cpp
-- core/autoencoder.h
-- core/common.h
-- core/device.cpp
-- core/device.h
-- core/transfer_function.cpp
-
-- scripts/resource_to_cpp.py (used in modules/denoise/resource_to_cpp.py)
-
-
## openxr
- Upstream: https://github.com/KhronosGroup/OpenXR-SDK
diff --git a/thirdparty/oidn/LICENSE.txt b/thirdparty/oidn/LICENSE.txt
deleted file mode 100644
index d6456956733..00000000000
--- a/thirdparty/oidn/LICENSE.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/thirdparty/oidn/common/barrier.h b/thirdparty/oidn/common/barrier.h
deleted file mode 100644
index b20f670053b..00000000000
--- a/thirdparty/oidn/common/barrier.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// ======================================================================== //
-// Copyright 2009-2019 Intel Corporation //
-// //
-// Licensed under the Apache License, Version 2.0 (the "License"); //
-// you may not use this file except in compliance with the License. //
-// You may obtain a copy of the License at //
-// //
-// http://www.apache.org/licenses/LICENSE-2.0 //
-// //
-// Unless required by applicable law or agreed to in writing, software //
-// distributed under the License is distributed on an "AS IS" BASIS, //
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
-// See the License for the specific language governing permissions and //
-// limitations under the License. //
-// ======================================================================== //
-
-#pragma once
-
-#include "platform.h"
-#include
-#include
-
-namespace oidn {
-
- class Barrier
- {
- private:
- std::mutex m;
- std::condition_variable cv;
- volatile int count;
-
- public:
- Barrier(int count) : count(count) {}
-
- void wait()
- {
- std::unique_lock lk(m);
- count--;
-
- if (count == 0)
- {
- lk.unlock();
- cv.notify_all();
- }
- else
- {
- cv.wait(lk, [&]{ return count == 0; });
- }
- }
- };
-
-} // namespace oidn
diff --git a/thirdparty/oidn/common/exception.h b/thirdparty/oidn/common/exception.h
deleted file mode 100644
index 18069c6a7dc..00000000000
--- a/thirdparty/oidn/common/exception.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// ======================================================================== //
-// Copyright 2009-2019 Intel Corporation //
-// //
-// Licensed under the Apache License, Version 2.0 (the "License"); //
-// you may not use this file except in compliance with the License. //
-// You may obtain a copy of the License at //
-// //
-// http://www.apache.org/licenses/LICENSE-2.0 //
-// //
-// Unless required by applicable law or agreed to in writing, software //
-// distributed under the License is distributed on an "AS IS" BASIS, //
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
-// See the License for the specific language governing permissions and //
-// limitations under the License. //
-// ======================================================================== //
-
-#pragma once
-
-#include
-#include "platform.h"
-
-namespace oidn {
-
- class Exception : public std::exception
- {
- private:
- Error error;
- const char* message;
-
- public:
- Exception(Error error, const char* message)
- : error(error), message(message) {}
-
- Error code() const noexcept
- {
- return error;
- }
-
- const char* what() const noexcept override
- {
- return message;
- }
- };
-
-} // namespace oidn
diff --git a/thirdparty/oidn/common/platform.cpp b/thirdparty/oidn/common/platform.cpp
deleted file mode 100644
index 59a14ff47c1..00000000000
--- a/thirdparty/oidn/common/platform.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-// ======================================================================== //
-// Copyright 2009-2019 Intel Corporation //
-// //
-// Licensed under the Apache License, Version 2.0 (the "License"); //
-// you may not use this file except in compliance with the License. //
-// You may obtain a copy of the License at //
-// //
-// http://www.apache.org/licenses/LICENSE-2.0 //
-// //
-// Unless required by applicable law or agreed to in writing, software //
-// distributed under the License is distributed on an "AS IS" BASIS, //
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
-// See the License for the specific language governing permissions and //
-// limitations under the License. //
-// ======================================================================== //
-
-#include "platform.h"
-
-namespace oidn {
-
- // ----------------------------------------------------------------------------
- // Common functions
- // ----------------------------------------------------------------------------
-
- void* alignedMalloc(size_t size, size_t alignment)
- {
- if (size == 0)
- return nullptr;
-
- assert((alignment & (alignment-1)) == 0);
- void* ptr = _mm_malloc(size, alignment);
-
- if (ptr == nullptr)
- throw std::bad_alloc();
-
- return ptr;
- }
-
- void alignedFree(void* ptr)
- {
- if (ptr)
- _mm_free(ptr);
- }
-
- // ----------------------------------------------------------------------------
- // System information
- // ----------------------------------------------------------------------------
-
- std::string getPlatformName()
- {
- std::string name;
-
- #if defined(__linux__)
- name = "Linux";
- #elif defined(__FreeBSD__)
- name = "FreeBSD";
- #elif defined(__CYGWIN__)
- name = "Cygwin";
- #elif defined(_WIN32)
- name = "Windows";
- #elif defined(__APPLE__)
- name = "macOS";
- #elif defined(__unix__)
- name = "Unix";
- #else
- return "Unknown";
- #endif
-
- #if defined(__x86_64__) || defined(_M_X64) || defined(__ia64__) || defined(__aarch64__)
- name += " (64-bit)";
- #else
- name += " (32-bit)";
- #endif
-
- return name;
- }
-
- std::string getCompilerName()
- {
- #if defined(__INTEL_COMPILER)
- int mayor = __INTEL_COMPILER / 100 % 100;
- int minor = __INTEL_COMPILER % 100;
- std::string version = "Intel Compiler ";
- version += toString(mayor);
- version += "." + toString(minor);
- #if defined(__INTEL_COMPILER_UPDATE)
- version += "." + toString(__INTEL_COMPILER_UPDATE);
- #endif
- return version;
- #elif defined(__clang__)
- return "Clang " __clang_version__;
- #elif defined(__GNUC__)
- return "GCC " __VERSION__;
- #elif defined(_MSC_VER)
- std::string version = toString(_MSC_FULL_VER);
- version.insert(4, ".");
- version.insert(9, ".");
- version.insert(2, ".");
- return "Visual C++ Compiler " + version;
- #else
- return "Unknown";
- #endif
- }
-
- std::string getBuildName()
- {
- #if defined(NDEBUG)
- return "Release";
- #else
- return "Debug";
- #endif
- }
-
-} // namespace oidn
diff --git a/thirdparty/oidn/common/platform.h b/thirdparty/oidn/common/platform.h
deleted file mode 100644
index 9373b617b57..00000000000
--- a/thirdparty/oidn/common/platform.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// ======================================================================== //
-// Copyright 2009-2019 Intel Corporation //
-// //
-// Licensed under the Apache License, Version 2.0 (the "License"); //
-// you may not use this file except in compliance with the License. //
-// You may obtain a copy of the License at //
-// //
-// http://www.apache.org/licenses/LICENSE-2.0 //
-// //
-// Unless required by applicable law or agreed to in writing, software //
-// distributed under the License is distributed on an "AS IS" BASIS, //
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
-// See the License for the specific language governing permissions and //
-// limitations under the License. //
-// ======================================================================== //
-
-#pragma once
-
-#if defined(_WIN32)
- #define WIN32_LEAN_AND_MEAN
- #define NOMINMAX
- #include
-#elif defined(__APPLE__)
- #include
-#endif
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "include/OpenImageDenoise/oidn.hpp"
-
-namespace oidn {
-
- // ----------------------------------------------------------------------------
- // Macros
- // ----------------------------------------------------------------------------
-
- #if defined(_WIN32)
- // Windows
- #if !defined(__noinline)
- #define __noinline __declspec(noinline)
- #endif
- #else
- // Unix
- #if !defined(__forceinline)
- #define __forceinline inline __attribute__((always_inline))
- #endif
- #if !defined(__noinline)
- #define __noinline __attribute__((noinline))
- #endif
- #endif
-
- #ifndef UNUSED
- #define UNUSED(x) ((void)x)
- #endif
- #ifndef MAYBE_UNUSED
- #define MAYBE_UNUSED(x) UNUSED(x)
- #endif
-
- // ----------------------------------------------------------------------------
- // Error handling and debugging
- // ----------------------------------------------------------------------------
-
- struct Verbose
- {
- int verbose;
-
- Verbose(int v = 0) : verbose(v) {}
- __forceinline bool isVerbose(int v = 1) const { return v <= verbose; }
- };
-
- #define OIDN_WARNING(message) { if (isVerbose()) std::cerr << "Warning: " << message << std::endl; }
- #define OIDN_FATAL(message) throw std::runtime_error(message);
-
- // ----------------------------------------------------------------------------
- // Common functions
- // ----------------------------------------------------------------------------
-
- using std::min;
- using std::max;
-
- template
- __forceinline T clamp(const T& value, const T& minValue, const T& maxValue)
- {
- return min(max(value, minValue), maxValue);
- }
-
- void* alignedMalloc(size_t size, size_t alignment);
- void alignedFree(void* ptr);
-
- template
- inline std::string toString(const T& a)
- {
- std::stringstream sm;
- sm << a;
- return sm.str();
- }
-
-#if defined(__APPLE__)
- template
- bool getSysctl(const char* name, T& value)
- {
- int64_t result = 0;
- size_t size = sizeof(result);
-
- if (sysctlbyname(name, &result, &size, nullptr, 0) != 0)
- return false;
-
- value = T(result);
- return true;
- }
-#endif
-
- // ----------------------------------------------------------------------------
- // System information
- // ----------------------------------------------------------------------------
-
- std::string getPlatformName();
- std::string getCompilerName();
- std::string getBuildName();
-
-} // namespace oidn
diff --git a/thirdparty/oidn/common/ref.h b/thirdparty/oidn/common/ref.h
deleted file mode 100644
index de44603af20..00000000000
--- a/thirdparty/oidn/common/ref.h
+++ /dev/null
@@ -1,163 +0,0 @@
-// ======================================================================== //
-// Copyright 2009-2019 Intel Corporation //
-// //
-// Licensed under the Apache License, Version 2.0 (the "License"); //
-// you may not use this file except in compliance with the License. //
-// You may obtain a copy of the License at //
-// //
-// http://www.apache.org/licenses/LICENSE-2.0 //
-// //
-// Unless required by applicable law or agreed to in writing, software //
-// distributed under the License is distributed on an "AS IS" BASIS, //
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
-// See the License for the specific language governing permissions and //
-// limitations under the License. //
-// ======================================================================== //
-
-#pragma once
-
-#include "platform.h"
-
-namespace oidn {
-
- class RefCount
- {
- private:
- std::atomic count;
-
- public:
- __forceinline RefCount(int count = 0) noexcept : count(count) {}
-
- __forceinline size_t incRef() noexcept
- {
- return count.fetch_add(1) + 1;
- }
-
- __forceinline size_t decRef()
- {
- const size_t newCount = decRefKeep();
- if (newCount == 0)
- destroy();
- return newCount;
- }
-
- __forceinline size_t decRefKeep() noexcept
- {
- return count.fetch_add(-1) - 1;
- }
-
- __forceinline void destroy()
- {
- delete this;
- }
-
- protected:
- // Disable copying
- RefCount(const RefCount&) = delete;
- RefCount& operator =(const RefCount&) = delete;
-
- virtual ~RefCount() noexcept = default;
- };
-
- template
- class Ref
- {
- private:
- T* ptr;
-
- public:
- __forceinline Ref() noexcept : ptr(nullptr) {}
- __forceinline Ref(std::nullptr_t) noexcept : ptr(nullptr) {}
- __forceinline Ref(const Ref& other) noexcept : ptr(other.ptr) { if (ptr) ptr->incRef(); }
- __forceinline Ref(Ref&& other) noexcept : ptr(other.ptr) { other.ptr = nullptr; }
- __forceinline Ref(T* ptr) noexcept : ptr(ptr) { if (ptr) ptr->incRef(); }
-
- template
- __forceinline Ref(const Ref& other) noexcept : ptr(other.get()) { if (ptr) ptr->incRef(); }
-
- template
- __forceinline explicit Ref(Y* ptr) noexcept : ptr(ptr) { if (ptr) ptr->incRef(); }
-
- __forceinline ~Ref() { if (ptr) ptr->decRef(); }
-
- __forceinline Ref& operator =(const Ref& other)
- {
- if (other.ptr)
- other.ptr->incRef();
- if (ptr)
- ptr->decRef();
- ptr = other.ptr;
- return *this;
- }
-
- __forceinline Ref& operator =(Ref&& other)
- {
- if (ptr)
- ptr->decRef();
- ptr = other.ptr;
- other.ptr = nullptr;
- return *this;
- }
-
- __forceinline Ref& operator =(T* other)
- {
- if (other)
- other->incRef();
- if (ptr)
- ptr->decRef();
- ptr = other;
- return *this;
- }
-
- __forceinline Ref& operator =(std::nullptr_t)
- {
- if (ptr)
- ptr->decRef();
- ptr = nullptr;
- return *this;
- }
-
- __forceinline operator bool() const noexcept { return ptr != nullptr; }
-
- __forceinline T& operator *() const noexcept { return *ptr; }
- __forceinline T* operator ->() const noexcept { return ptr; }
-
- __forceinline T* get() const noexcept { return ptr; }
-
- __forceinline T* detach() noexcept
- {
- T* res = ptr;
- ptr = nullptr;
- return res;
- }
- };
-
- template __forceinline bool operator < (const Ref& a, const Ref& b) noexcept { return a.ptr < b.ptr; }
-
- template __forceinline bool operator ==(const Ref& a, std::nullptr_t) noexcept { return a.ptr == nullptr; }
- template __forceinline bool operator ==(std::nullptr_t, const Ref& b) noexcept { return nullptr == b.ptr; }
- template __forceinline bool operator ==(const Ref& a, const Ref& b) noexcept { return a.ptr == b.ptr; }
-
- template __forceinline bool operator !=(const Ref& a, std::nullptr_t) noexcept { return a.ptr != nullptr; }
- template __forceinline bool operator !=(std::nullptr_t, const Ref& b) noexcept { return nullptr != b.ptr; }
- template __forceinline bool operator !=(const Ref& a, const Ref& b) noexcept { return a.ptr != b.ptr; }
-
- template
- __forceinline Ref makeRef(Args&&... args)
- {
- return Ref(new T(std::forward(args)...));
- }
-
- template
- __forceinline Ref staticRefCast(const Ref& a)
- {
- return Ref(static_cast(a.get()));
- }
-
- template
- __forceinline Ref dynamicRefCast(const Ref& a)
- {
- return Ref(dynamic_cast(a.get()));
- }
-
-} // namespace oidn
diff --git a/thirdparty/oidn/common/tensor.cpp b/thirdparty/oidn/common/tensor.cpp
deleted file mode 100644
index 0249f2e1419..00000000000
--- a/thirdparty/oidn/common/tensor.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-// ======================================================================== //
-// Copyright 2009-2019 Intel Corporation //
-// //
-// Licensed under the Apache License, Version 2.0 (the "License"); //
-// you may not use this file except in compliance with the License. //
-// You may obtain a copy of the License at //
-// //
-// http://www.apache.org/licenses/LICENSE-2.0 //
-// //
-// Unless required by applicable law or agreed to in writing, software //
-// distributed under the License is distributed on an "AS IS" BASIS, //
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
-// See the License for the specific language governing permissions and //
-// limitations under the License. //
-// ======================================================================== //
-
-#include "exception.h"
-#include "tensor.h"
-
-namespace oidn {
-
- std::map parseTensors(void* buffer)
- {
- char* input = (char*)buffer;
-
- // Parse the magic value
- const int magic = *(unsigned short*)input;
- if (magic != 0x41D7)
- throw Exception(Error::InvalidOperation, "invalid tensor archive");
- input += sizeof(unsigned short);
-
- // Parse the version
- const int majorVersion = *(unsigned char*)input++;
- const int minorVersion = *(unsigned char*)input++;
- UNUSED(minorVersion);
- if (majorVersion > 1)
- throw Exception(Error::InvalidOperation, "unsupported tensor archive version");
-
- // Parse the number of tensors
- const int numTensors = *(int*)input;
- input += sizeof(int);
-
- // Parse the tensors
- std::map tensorMap;
- for (int i = 0; i < numTensors; ++i)
- {
- Tensor tensor;
-
- // Parse the name
- const int nameLen = *(unsigned char*)input++;
- std::string name(input, nameLen);
- input += nameLen;
-
- // Parse the number of dimensions
- const int ndims = *(unsigned char*)input++;
-
- // Parse the shape of the tensor
- tensor.dims.resize(ndims);
- for (int i = 0; i < ndims; ++i)
- tensor.dims[i] = ((int*)input)[i];
- input += ndims * sizeof(int);
-
- // Parse the format of the tensor
- tensor.format = std::string(input, input + ndims);
- input += ndims;
-
- // Parse the data type of the tensor
- const char type = *(unsigned char*)input++;
- if (type != 'f') // only float32 is supported
- throw Exception(Error::InvalidOperation, "unsupported tensor data type");
-
- // Skip the data
- tensor.data = (float*)input;
- input += tensor.size() * sizeof(float);
-
- // Add the tensor to the map
- tensorMap.emplace(name, std::move(tensor));
- }
-
- return tensorMap;
- }
-
-} // namespace oidn
diff --git a/thirdparty/oidn/common/tensor.h b/thirdparty/oidn/common/tensor.h
deleted file mode 100644
index 48e7d1123d1..00000000000
--- a/thirdparty/oidn/common/tensor.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// ======================================================================== //
-// Copyright 2009-2019 Intel Corporation //
-// //
-// Licensed under the Apache License, Version 2.0 (the "License"); //
-// you may not use this file except in compliance with the License. //
-// You may obtain a copy of the License at //
-// //
-// http://www.apache.org/licenses/LICENSE-2.0 //
-// //
-// Unless required by applicable law or agreed to in writing, software //
-// distributed under the License is distributed on an "AS IS" BASIS, //
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
-// See the License for the specific language governing permissions and //
-// limitations under the License. //
-// ======================================================================== //
-
-#pragma once
-
-#include "platform.h"
-#include
-#include ]