Browse Source

LightmapGI: Pack L1 SH coefficients before denoising

BlueCube3310 3 months ago
parent
commit
de9b22625e

+ 9 - 8
modules/lightmapper_rd/lightmapper_rd.cpp

@@ -980,6 +980,7 @@ LightmapperRD::BakeError LightmapperRD::_denoise(RenderingDevice *p_rd, Ref<RDSh
 	denoise_params.normal_bandwidth = 0.1f;
 	denoise_params.normal_bandwidth = 0.1f;
 	denoise_params.filter_strength = 10.0f;
 	denoise_params.filter_strength = 10.0f;
 	denoise_params.half_search_window = p_denoiser_range;
 	denoise_params.half_search_window = p_denoiser_range;
+	denoise_params.slice_count = p_bake_sh ? 4 : 1;
 	p_rd->buffer_update(denoise_params_buffer, 0, sizeof(DenoiseParams), &denoise_params);
 	p_rd->buffer_update(denoise_params_buffer, 0, sizeof(DenoiseParams), &denoise_params);
 
 
 	Vector<RD::Uniform> uniforms = dilate_or_denoise_common_uniforms(p_source_light_tex, p_dest_light_tex);
 	Vector<RD::Uniform> uniforms = dilate_or_denoise_common_uniforms(p_source_light_tex, p_dest_light_tex);
@@ -2065,6 +2066,14 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
 
 
 	/* DENOISE */
 	/* DENOISE */
 
 
+	if (p_bake_sh) {
+		SWAP(light_accum_tex, light_accum_tex2);
+		BakeError error = _pack_l1(rd, compute_shader, compute_base_uniform_set, push_constant, light_accum_tex2, light_accum_tex, atlas_size, atlas_slices);
+		if (unlikely(error != BAKE_OK)) {
+			return error;
+		}
+	}
+
 	if (p_use_denoiser) {
 	if (p_use_denoiser) {
 		if (p_step_function) {
 		if (p_step_function) {
 			if (p_step_function(0.8, RTR("Denoising"), p_bake_userdata, true)) {
 			if (p_step_function(0.8, RTR("Denoising"), p_bake_userdata, true)) {
@@ -2290,14 +2299,6 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
 		}
 		}
 	}
 	}
 
 
-	if (p_bake_sh) {
-		SWAP(light_accum_tex, light_accum_tex2);
-		BakeError error = _pack_l1(rd, compute_shader, compute_base_uniform_set, push_constant, light_accum_tex2, light_accum_tex, atlas_size, atlas_slices);
-		if (unlikely(error != BAKE_OK)) {
-			return error;
-		}
-	}
-
 #ifdef DEBUG_TEXTURES
 #ifdef DEBUG_TEXTURES
 
 
 	for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) {
 	for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) {

+ 2 - 1
modules/lightmapper_rd/lightmapper_rd.h

@@ -281,7 +281,8 @@ class LightmapperRD : public Lightmapper {
 
 
 		int half_search_window;
 		int half_search_window;
 		float filter_strength;
 		float filter_strength;
-		float pad[2];
+		uint32_t slice_count;
+		uint32_t pad;
 	};
 	};
 
 
 	BakeError _blit_meshes_into_atlas(int p_max_texture_size, int p_denoiser_range, Vector<Ref<Image>> &albedo_images, Vector<Ref<Image>> &emission_images, AABB &bounds, Size2i &atlas_size, int &atlas_slices, float p_supersampling_factor, BakeStepFunc p_step_function, void *p_bake_userdata);
 	BakeError _blit_meshes_into_atlas(int p_max_texture_size, int p_denoiser_range, Vector<Ref<Image>> &albedo_images, Vector<Ref<Image>> &emission_images, AABB &bounds, Size2i &atlas_size, int &atlas_slices, float p_supersampling_factor, BakeStepFunc p_step_function, void *p_bake_userdata);

+ 15 - 22
modules/lightmapper_rd/lm_compute.glsl

@@ -82,6 +82,7 @@ layout(set = 1, binding = 4) uniform DenoiseParams {
 
 
 	int half_search_window;
 	int half_search_window;
 	float filter_strength;
 	float filter_strength;
+	uint slice_count;
 }
 }
 denoise_params;
 denoise_params;
 #endif
 #endif
@@ -1193,13 +1194,9 @@ void main() {
 	const float FILTER_SQUARE_TWO_SIGMA_LIGHT_SQUARE = FILTER_VALUE * FILTER_VALUE * TWO_SIGMA_LIGHT_SQUARE;
 	const float FILTER_SQUARE_TWO_SIGMA_LIGHT_SQUARE = FILTER_VALUE * FILTER_VALUE * TWO_SIGMA_LIGHT_SQUARE;
 	const float EPSILON = 1e-6f;
 	const float EPSILON = 1e-6f;
 
 
-#ifdef USE_SH_LIGHTMAPS
-	const uint slice_count = 4;
+	const uint slice_count = denoise_params.slice_count;
 	const uint slice_base = params.atlas_slice * slice_count;
 	const uint slice_base = params.atlas_slice * slice_count;
-#else
-	const uint slice_count = 1;
-	const uint slice_base = params.atlas_slice;
-#endif
+	const bool is_directional = (slice_count == 4);
 
 
 	for (uint i = 0; i < slice_count; i++) {
 	for (uint i = 0; i < slice_count; i++) {
 		uint lightmap_slice = slice_base + i;
 		uint lightmap_slice = slice_base + i;
@@ -1223,9 +1220,16 @@ void main() {
 						for (int offset_x = -HALF_PATCH_WINDOW; offset_x <= HALF_PATCH_WINDOW; offset_x++) {
 						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_input_pos = atlas_pos + ivec2(offset_x, offset_y);
 							ivec2 offset_search_pos = search_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_input_rgb = texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(offset_input_pos, slice_base), 0).rgb;
+							vec3 offset_search_rgb = texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(offset_search_pos, slice_base), 0).rgb;
 							vec3 offset_delta_rgb = offset_input_rgb - offset_search_rgb;
 							vec3 offset_delta_rgb = offset_input_rgb - offset_search_rgb;
+
+							if (is_directional) {
+								// Since L0 data is 1/4 the value of a regular lightmap,
+								// we have to multiply it by 4.
+								offset_delta_rgb *= 4.0;
+							}
+
 							patch_square_dist += dot(offset_delta_rgb, offset_delta_rgb) - TWO_SIGMA_LIGHT_SQUARE;
 							patch_square_dist += dot(offset_delta_rgb, offset_delta_rgb) - TWO_SIGMA_LIGHT_SQUARE;
 						}
 						}
 					}
 					}
@@ -1280,24 +1284,13 @@ void main() {
 
 
 #ifdef MODE_PACK_L1_COEFFS
 #ifdef MODE_PACK_L1_COEFFS
 	vec4 base_coeff = texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos, params.atlas_slice * 4), 0);
 	vec4 base_coeff = texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos, params.atlas_slice * 4), 0);
+	imageStore(dest_light, ivec3(atlas_pos, params.atlas_slice * 4), base_coeff);
 
 
 	for (int i = 1; i < 4; i++) {
 	for (int i = 1; i < 4; i++) {
 		vec4 c = texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos, params.atlas_slice * 4 + i), 0);
 		vec4 c = texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos, params.atlas_slice * 4 + i), 0);
+		c.rgb /= (base_coeff.rgb * 8.0 + vec3(1e-6f));
+		c.rgb = clamp(c.rgb + vec3(0.5), vec3(0.0), vec3(1.0));
 
 
-		if (abs(base_coeff.r) > 0.0) {
-			c.r /= (base_coeff.r * 8);
-		}
-
-		if (abs(base_coeff.g) > 0.0) {
-			c.g /= (base_coeff.g * 8);
-		}
-
-		if (abs(base_coeff.b) > 0.0) {
-			c.b /= (base_coeff.b * 8);
-		}
-
-		c.rgb += vec3(0.5);
-		c.rgb = clamp(c.rgb, vec3(0.0), vec3(1.0));
 		imageStore(dest_light, ivec3(atlas_pos, params.atlas_slice * 4 + i), c);
 		imageStore(dest_light, ivec3(atlas_pos, params.atlas_slice * 4 + i), c);
 	}
 	}
 #endif
 #endif