Fix: EEVEE-Next: Fix spherical harmonic clamping
The previous implementation was not considering each channel magnitude, which was not rotationally invariant. This fixes changes in lighting as the world rotates (and if clamping is enabled).
This commit is contained in:
@@ -136,6 +136,7 @@ void main()
|
||||
* Note that this is an approximation since the footprint of a thread-group is not
|
||||
* necessarily a convex polygons (with center of gravity at midpoint).
|
||||
* But the actual error introduce by this approximation is not perceivable. */
|
||||
/* FIXME(fclem): The error IS very perceivable for resolution lower than a quadrant. */
|
||||
ivec2 max_group_texel = local_texel + ivec2(gl_WorkGroupSize.xy);
|
||||
/* Min direction is the local direction since this is only ran by thread 0. */
|
||||
vec3 min_direction = normalize(direction);
|
||||
|
||||
@@ -718,12 +718,13 @@ SphericalHarmonicL1 spherical_harmonics_clamp(SphericalHarmonicL1 sh, float clam
|
||||
{
|
||||
/* Convert coefficients to per channel column. */
|
||||
mat4x4 per_channel = transpose(mat4x4(sh.L0.M0, sh.L1.Mn1, sh.L1.M0, sh.L1.Mp1));
|
||||
/* Maximum per channel. */
|
||||
vec3 max_L1 = vec3(reduce_max(abs(per_channel[0].yzw)),
|
||||
reduce_max(abs(per_channel[1].yzw)),
|
||||
reduce_max(abs(per_channel[2].yzw)));
|
||||
/* Magnitute per channel. */
|
||||
vec3 mag_L1;
|
||||
mag_L1.r = length(per_channel[0].yzw);
|
||||
mag_L1.g = length(per_channel[1].yzw);
|
||||
mag_L1.b = length(per_channel[2].yzw);
|
||||
/* Find maximum of the sh function over all channels. */
|
||||
vec3 max_sh = abs(sh.L0.M0.rgb) * 0.282094792 + max_L1 * 0.488602512;
|
||||
vec3 max_sh = abs(sh.L0.M0.rgb) * 0.282094792 + mag_L1 * 0.488602512;
|
||||
|
||||
float fac = clamp_value * safe_rcp(reduce_max(max_sh));
|
||||
if (fac > 1.0) {
|
||||
|
||||
Reference in New Issue
Block a user