Skip to content

Commit 36d7a87

Browse files
committed
Merge pull request #107168 from Rudolph-B/Issue-102300
Fix SH lightmap coefficients for direct lights
2 parents 85fedec + 9b00031 commit 36d7a87

1 file changed

Lines changed: 24 additions & 8 deletions

File tree

modules/lightmapper_rd/lm_compute.glsl

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -861,16 +861,32 @@ void main() {
861861
light_for_texture += light;
862862

863863
#ifdef USE_SH_LIGHTMAPS
864-
// 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.
865-
// LO: 1/(2*sqrtPI) * 1/(2*sqrtPI) * PI * PI * 1/PI = 0.25
866-
// L1: sqrt(3/(4*pi)) * sqrt(3/(4*pi)) * (PI*2/3) * (2 * PI) * 1/PI = 1.0
867-
// Note: This only works because we aren't scaling, rotating, or combing harmonics, we are just directing applying them in the shader.
864+
// For L0, light needs to be attenuated by dot(normal, light_dir) else it is oversaturated when sampled later.
865+
// For L1, light can't be attenuated by dot(normal, light_dir) since when sampling later, the dot product is done.
866+
// The output of trace_direct_light() is already attenuated by dot(normal, light_dir).
867+
// So L0 and L1 has the following relationship: L1 = L0 / dot(normal, light_dir).
868868

869+
// For L1 packing to work, there needs to be a defined ratio (4) between L0 and L1 values.
870+
// This ratio is achieved with two coefficients c_l0 and c_l1, and ensuring that
871+
// 4 = (c_l0 * LO) / (c_l1 * L1)
872+
873+
// For direct lights to look right, its effective "energy" needs to be 1 since it is not being integrated
874+
// unlike indirect lighting.
875+
// This binds c_l0 and c_l1 to the following relationship: 1 = c_l0 + c_l1
876+
877+
float attenuation = dot(normal, light_dir);
878+
879+
if (attenuation <= 0.0001) {
880+
continue;
881+
}
882+
883+
float c_l0 = 1 / (1 + 4 * attenuation);
884+
float c_l1 = 1 - c_l0;
869885
float c[4] = float[](
870-
0.25, //l0
871-
light_dir.y, //l1n1
872-
light_dir.z, //l1n0
873-
light_dir.x //l1p1
886+
c_l0, //l0
887+
c_l1 / attenuation * light_dir.y, //l1n1
888+
c_l1 / attenuation * light_dir.z, //l1n0
889+
c_l1 / attenuation * light_dir.x //l1p1
874890
);
875891

876892
for (uint j = 0; j < 4; j++) {

0 commit comments

Comments
 (0)