Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use correct lightmap coefficients to ensure that the directional lightmap mode looks correct #95888

Merged
merged 1 commit into from
Aug 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 4 additions & 10 deletions drivers/gles3/shaders/scene.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 15 additions & 2 deletions modules/lightmapper_rd/lightmapper_rd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,7 @@ LightmapperRD::BakeError LightmapperRD::_denoise_oidn(RenderingDevice *p_rd, RID
return BAKE_OK;
}

LightmapperRD::BakeError LightmapperRD::_denoise(RenderingDevice *p_rd, Ref<RDShaderFile> &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<RDShaderFile> &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;
Expand Down Expand Up @@ -978,6 +978,11 @@ LightmapperRD::BakeError LightmapperRD::_denoise(RenderingDevice *p_rd, Ref<RDSh
p_rd->sync();
}
}
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);
Expand Down Expand Up @@ -1581,6 +1586,14 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
Ref<Image> 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<uint8_t> s = rd->texture_get_data(light_accum_tex, i);
Ref<Image> 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) */
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion modules/lightmapper_rd/lightmapper_rd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<int> 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<RDShaderFile> &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<RDShaderFile> &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<RDShaderFile> &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<Image> _read_pfm(const String &p_name);
Expand Down
30 changes: 20 additions & 10 deletions modules/lightmapper_rd/lm_compute.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Loading