2
0
Эх сурвалжийг харах

Merge pull request #58164 from Calinou/import-hdr-add-clamp-exposure-option

Add an option to clamp HDR exposure to reduce environment fireflies
Rémi Verschelde 3 жил өмнө
parent
commit
6e67dc0881

+ 30 - 0
editor/import/resource_importer_texture.cpp

@@ -221,6 +221,7 @@ void ResourceImporterTexture::get_import_options(const String &p_path, List<Impo
 	r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/premult_alpha"), false));
 	r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/premult_alpha"), false));
 	r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/normal_map_invert_y"), false));
 	r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/normal_map_invert_y"), false));
 	r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/hdr_as_srgb"), false));
 	r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/hdr_as_srgb"), false));
+	r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/hdr_clamp_exposure"), false));
 	r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "process/size_limit", PROPERTY_HINT_RANGE, "0,4096,1"), 0));
 	r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "process/size_limit", PROPERTY_HINT_RANGE, "0,4096,1"), 0));
 	r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "detect_3d/compress_to", PROPERTY_HINT_ENUM, "Disabled,VRAM Compressed,Basis Universal"), (p_preset == PRESET_DETECT) ? 1 : 0));
 	r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "detect_3d/compress_to", PROPERTY_HINT_ENUM, "Disabled,VRAM Compressed,Basis Universal"), (p_preset == PRESET_DETECT) ? 1 : 0));
 
 
@@ -414,6 +415,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
 	const bool stream = false;
 	const bool stream = false;
 	const int size_limit = p_options["process/size_limit"];
 	const int size_limit = p_options["process/size_limit"];
 	const bool hdr_as_srgb = p_options["process/hdr_as_srgb"];
 	const bool hdr_as_srgb = p_options["process/hdr_as_srgb"];
+	const bool hdr_clamp_exposure = p_options["process/hdr_clamp_exposure"];
 	const int normal = p_options["compress/normal_map"];
 	const int normal = p_options["compress/normal_map"];
 	const int hdr_compression = p_options["compress/hdr_compression"];
 	const int hdr_compression = p_options["compress/hdr_compression"];
 	const int bptc_ldr = p_options["compress/bptc_ldr"];
 	const int bptc_ldr = p_options["compress/bptc_ldr"];
@@ -485,6 +487,34 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
 		}
 		}
 	}
 	}
 
 
+	if (hdr_clamp_exposure) {
+		// Clamp HDR exposure following Filament's tonemapping formula.
+		// This can be used to reduce fireflies in environment maps or reduce the influence
+		// of the sun from an HDRI panorama on environment lighting (when a DirectionalLight3D is used instead).
+		const int height = image->get_height();
+		const int width = image->get_width();
+
+		// These values are chosen arbitrarily and seem to produce good results with 4,096 samples.
+		const float linear = 4096.0;
+		const float compressed = 16384.0;
+
+		for (int i = 0; i < width; i++) {
+			for (int j = 0; j < height; j++) {
+				const Color color = image->get_pixel(i, j);
+				const float luma = color.get_luminance();
+
+				Color clamped_color;
+				if (luma <= linear) {
+					clamped_color = color;
+				} else {
+					clamped_color = (color / luma) * ((linear * linear - compressed * luma) / (2 * linear - compressed - luma));
+				}
+
+				image->set_pixel(i, j, clamped_color);
+			}
+		}
+	}
+
 	if (compress_mode == COMPRESS_BASIS_UNIVERSAL && image->get_format() >= Image::FORMAT_RF) {
 	if (compress_mode == COMPRESS_BASIS_UNIVERSAL && image->get_format() >= Image::FORMAT_RF) {
 		//basis universal does not support float formats, fall back
 		//basis universal does not support float formats, fall back
 		compress_mode = COMPRESS_VRAM_COMPRESSED;
 		compress_mode = COMPRESS_VRAM_COMPRESSED;