diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 04ba98a4205..955f3e02060 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -1729,16 +1729,10 @@ void main() { vec3 n = normalize(lightmap_normal_xform * normal); - ambient_light += lm_light_l0 * 0.282095f; - ambient_light += lm_light_l1n1 * 0.32573 * n.y * lightmap_exposure_normalization; - ambient_light += lm_light_l1_0 * 0.32573 * n.z * lightmap_exposure_normalization; - ambient_light += lm_light_l1p1 * 0.32573 * n.x * lightmap_exposure_normalization; - if (metallic > 0.01) { // Since the more direct bounced light is lost, we can kind of fake it with this trick. - vec3 r = reflect(normalize(-vertex), normal); - specular_light += lm_light_l1n1 * 0.32573 * r.y * lightmap_exposure_normalization; - specular_light += lm_light_l1_0 * 0.32573 * r.z * lightmap_exposure_normalization; - specular_light += lm_light_l1p1 * 0.32573 * r.x * lightmap_exposure_normalization; - } + ambient_light += lm_light_l0 * lightmap_exposure_normalization; + ambient_light += lm_light_l1n1 * n.y * lightmap_exposure_normalization; + ambient_light += lm_light_l1_0 * n.z * lightmap_exposure_normalization; + ambient_light += lm_light_l1p1 * n.x * lightmap_exposure_normalization; #else ambient_light += textureLod(lightmap_textures, uvw, 0.0).rgb * lightmap_exposure_normalization; #endif diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp index 33b0b0d0152..41ac6ee0ec8 100644 --- a/modules/lightmapper_rd/lightmapper_rd.cpp +++ b/modules/lightmapper_rd/lightmapper_rd.cpp @@ -915,7 +915,7 @@ LightmapperRD::BakeError LightmapperRD::_denoise_oidn(RenderingDevice *p_rd, RID return BAKE_OK; } -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, int p_denoiser_range, const Size2i &p_atlas_size, int p_atlas_slices, bool p_bake_sh, BakeStepFunc p_step_function) { +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, int p_denoiser_range, const Size2i &p_atlas_size, int p_atlas_slices, bool p_bake_sh, BakeStepFunc p_step_function, void *p_bake_userdata) { RID denoise_params_buffer = p_rd->uniform_buffer_create(sizeof(DenoiseParams)); DenoiseParams denoise_params; denoise_params.spatial_bandwidth = 5.0f; @@ -978,6 +978,11 @@ LightmapperRD::BakeError LightmapperRD::_denoise(RenderingDevice *p_rd, Refsync(); } } + if (p_step_function) { + int percent = (s + 1) * 100 / p_atlas_slices; + float p = float(s) / p_atlas_slices * 0.1; + p_step_function(0.8 + p, vformat(RTR("Denoising %d%%"), percent), p_bake_userdata, false); + } } p_rd->free(compute_shader_denoise); @@ -1581,6 +1586,14 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d Ref img = Image::create_from_data(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s); img->save_exr("res://2_light_primary_" + itos(i) + ".exr", false); } + + if (p_bake_sh) { + for (int i = 0; i < atlas_slices * 4; 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); + img->save_exr("res://2_light_primary_accum_" + itos(i) + ".exr", false); + } + } #endif /* SECONDARY (indirect) LIGHT PASS(ES) */ @@ -1803,7 +1816,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d } else { // JNLM (built-in). SWAP(light_accum_tex, light_accum_tex2); - error = _denoise(rd, compute_shader, compute_base_uniform_set, push_constant, light_accum_tex2, normal_tex, light_accum_tex, p_denoiser_strength, p_denoiser_range, atlas_size, atlas_slices, p_bake_sh, p_step_function); + error = _denoise(rd, compute_shader, compute_base_uniform_set, push_constant, light_accum_tex2, normal_tex, light_accum_tex, p_denoiser_strength, p_denoiser_range, atlas_size, atlas_slices, p_bake_sh, p_step_function, p_bake_userdata); } if (unlikely(error != BAKE_OK)) { return error; diff --git a/modules/lightmapper_rd/lightmapper_rd.h b/modules/lightmapper_rd/lightmapper_rd.h index 487c44a480a..59c2d52e697 100644 --- a/modules/lightmapper_rd/lightmapper_rd.h +++ b/modules/lightmapper_rd/lightmapper_rd.h @@ -272,7 +272,7 @@ class LightmapperRD : public Lightmapper { 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, int p_denoiser_range, const Size2i &p_atlas_size, int p_atlas_slices, bool p_bake_sh, BakeStepFunc p_step_function); + 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, int p_denoiser_range, const Size2i &p_atlas_size, int p_atlas_slices, bool p_bake_sh, BakeStepFunc p_step_function, void *p_bake_userdata); Error _store_pfm(RenderingDevice *p_rd, RID p_atlas_tex, int p_index, const Size2i &p_atlas_size, const String &p_name); Ref _read_pfm(const String &p_name); diff --git a/modules/lightmapper_rd/lm_compute.glsl b/modules/lightmapper_rd/lm_compute.glsl index 9424d5a4c11..6320d3afa7d 100644 --- a/modules/lightmapper_rd/lm_compute.glsl +++ b/modules/lightmapper_rd/lm_compute.glsl @@ -588,15 +588,20 @@ void main() { light_for_texture += light; #ifdef USE_SH_LIGHTMAPS + // These coefficients include the factored out SH evaluation, diffuse convolution, and final application, as well as the BRDF 1/PI and the spherical monte carlo factor. + // LO: 1/(2*sqrtPI) * 1/(2*sqrtPI) * PI * PI * 1/PI = 0.25 + // L1: sqrt(3/(4*pi)) * sqrt(3/(4*pi)) * (PI*2/3) * (2 * PI) * 1/PI = 1.0 + // Note: This only works because we aren't scaling, rotating, or combing harmonics, we are just directing applying them in the shader. + float c[4] = float[]( - 0.282095, //l0 - 0.488603 * light_dir.y, //l1n1 - 0.488603 * light_dir.z, //l1n0 - 0.488603 * light_dir.x //l1p1 + 0.25, //l0 + light_dir.y, //l1n1 + light_dir.z, //l1n0 + light_dir.x //l1p1 ); for (uint j = 0; j < 4; j++) { - sh_accum[j].rgb += light * c[j] * 8.0; + sh_accum[j].rgb += light * c[j] * bake_params.exposure_normalization; } #endif } @@ -646,15 +651,20 @@ void main() { vec3 light = trace_indirect_light(position, ray_dir, noise); #ifdef USE_SH_LIGHTMAPS + // These coefficients include the factored out SH evaluation, diffuse convolution, and final application, as well as the BRDF 1/PI and the spherical monte carlo factor. + // LO: 1/(2*sqrtPI) * 1/(2*sqrtPI) * PI * PI * 1/PI = 0.25 + // L1: sqrt(3/(4*pi)) * sqrt(3/(4*pi)) * (PI*2/3) * (2 * PI) * 1/PI = 1.0 + // Note: This only works because we aren't scaling, rotating, or combing harmonics, we are just directing applying them in the shader. + float c[4] = float[]( - 0.282095, //l0 - 0.488603 * ray_dir.y, //l1n1 - 0.488603 * ray_dir.z, //l1n0 - 0.488603 * ray_dir.x //l1p1 + 0.25, //l0 + ray_dir.y, //l1n1 + ray_dir.z, //l1n0 + ray_dir.x //l1p1 ); for (uint j = 0; j < 4; j++) { - sh_accum[j].rgb += light * c[j] * 8.0; + sh_accum[j].rgb += light * c[j]; } #else light_accum += light; diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl index cf15497c8c6..203ddd6610c 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl @@ -1450,16 +1450,10 @@ void fragment_shader(in SceneData scene_data) { vec3 n = normalize(lightmaps.data[ofs].normal_xform * normal); float en = lightmaps.data[ofs].exposure_normalization; - ambient_light += lm_light_l0 * 0.282095f * en; - ambient_light += lm_light_l1n1 * 0.32573 * n.y * en; - ambient_light += lm_light_l1_0 * 0.32573 * n.z * en; - ambient_light += lm_light_l1p1 * 0.32573 * n.x * en; - if (metallic > 0.01) { // since the more direct bounced light is lost, we can kind of fake it with this trick - vec3 r = reflect(normalize(-vertex), normal); - specular_light += lm_light_l1n1 * 0.32573 * r.y * en; - specular_light += lm_light_l1_0 * 0.32573 * r.z * en; - specular_light += lm_light_l1p1 * 0.32573 * r.x * en; - } + ambient_light += lm_light_l0 * en; + ambient_light += lm_light_l1n1 * n.y * en; + ambient_light += lm_light_l1_0 * n.z * en; + ambient_light += lm_light_l1p1 * n.x * en; } else { ambient_light += textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw, 0.0).rgb * lightmaps.data[ofs].exposure_normalization; diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl index e7623e0062e..2a250bfb342 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl @@ -1210,17 +1210,10 @@ void main() { vec3 n = normalize(lightmaps.data[ofs].normal_xform * normal); float exposure_normalization = lightmaps.data[ofs].exposure_normalization; - ambient_light += lm_light_l0 * 0.282095f; - ambient_light += lm_light_l1n1 * 0.32573 * n.y * exposure_normalization; - ambient_light += lm_light_l1_0 * 0.32573 * n.z * exposure_normalization; - ambient_light += lm_light_l1p1 * 0.32573 * n.x * exposure_normalization; - if (metallic > 0.01) { // since the more direct bounced light is lost, we can kind of fake it with this trick - vec3 r = reflect(normalize(-vertex), normal); - specular_light += lm_light_l1n1 * 0.32573 * r.y * exposure_normalization; - specular_light += lm_light_l1_0 * 0.32573 * r.z * exposure_normalization; - specular_light += lm_light_l1p1 * 0.32573 * r.x * exposure_normalization; - } - + ambient_light += lm_light_l0 * exposure_normalization; + ambient_light += lm_light_l1n1 * n.y * exposure_normalization; + ambient_light += lm_light_l1_0 * n.z * exposure_normalization; + ambient_light += lm_light_l1p1 * n.x * exposure_normalization; } else { ambient_light += textureLod(sampler2DArray(lightmap_textures[ofs], SAMPLER_LINEAR_CLAMP), uvw, 0.0).rgb * lightmaps.data[ofs].exposure_normalization; }