From b597c0f1edee3eae0108187e90dcdefe0d663a37 Mon Sep 17 00:00:00 2001 From: u3dreal Date: Thu, 16 Oct 2025 15:38:38 +0200 Subject: [PATCH] Fix: Cycles: IES interpolation artifacts at angular boundaries Fixes artifacts in IES data interpolation where edge samples (e.g., v == 0 or h_i == h_num-1) were clamped to 0.0f instead of valid intensity values. --- intern/cycles/kernel/util/ies.h | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/intern/cycles/kernel/util/ies.h b/intern/cycles/kernel/util/ies.h index ee09e526162..8642082c0a3 100644 --- a/intern/cycles/kernel/util/ies.h +++ b/intern/cycles/kernel/util/ies.h @@ -27,22 +27,29 @@ ccl_device_inline float interpolate_ies_vertical(KernelGlobals kg, * we can just take the corresponding value at the current horizontal coordinate. */ #define IES_LOOKUP(v) kernel_data_fetch(ies, ofs + h * v_num + (v)) - float a = 0.0f; + + /* Look up the inner two points directly. */ + const float c = IES_LOOKUP(v + 1); + const float b = IES_LOOKUP(v); + + /* Look up first point, or fall back to second point if not available. */ + float a = b; if (v > 0) { a = IES_LOOKUP(v - 1); } else if (wrap_vlow) { a = IES_LOOKUP(1); } - const float b = IES_LOOKUP(v); - const float c = IES_LOOKUP(v + 1); - float d = 0.0f; + + /* Look up last point, or fall back to third point if not available. */ + float d = c; if (v + 2 < v_num) { d = IES_LOOKUP(v + 2); } else if (wrap_vhigh) { d = IES_LOOKUP(v_num - 2); } + #undef IES_LOOKUP return cubic_interp(a, b, c, d, v_frac); @@ -105,7 +112,14 @@ ccl_device_inline float kernel_ies_interp(KernelGlobals kg, /* Skip forward to the actual intensity data. */ ofs += h_num + v_num; - float a = 0.0f; + /* Interpolate the inner two points directly. */ + const float b = interpolate_ies_vertical( + kg, ofs, wrap_vlow, wrap_vhigh, v_i, v_num, v_frac, h_i); + const float c = interpolate_ies_vertical( + kg, ofs, wrap_vlow, wrap_vhigh, v_i, v_num, v_frac, h_i + 1); + + /* Interpolate first point, or fall back to second point if not available. */ + float a = b; if (h_i > 0) { a = interpolate_ies_vertical(kg, ofs, wrap_vlow, wrap_vhigh, v_i, v_num, v_frac, h_i - 1); } @@ -113,11 +127,9 @@ ccl_device_inline float kernel_ies_interp(KernelGlobals kg, /* The last entry (360°) equals the first one, so we need to wrap around to the one before. */ a = interpolate_ies_vertical(kg, ofs, wrap_vlow, wrap_vhigh, v_i, v_num, v_frac, h_num - 2); } - const float b = interpolate_ies_vertical( - kg, ofs, wrap_vlow, wrap_vhigh, v_i, v_num, v_frac, h_i); - const float c = interpolate_ies_vertical( - kg, ofs, wrap_vlow, wrap_vhigh, v_i, v_num, v_frac, h_i + 1); - float d = 0.0f; + + /* Interpolate last point, or fall back to second point if not available. */ + float d = b; if (h_i + 2 < h_num) { d = interpolate_ies_vertical(kg, ofs, wrap_vlow, wrap_vhigh, v_i, v_num, v_frac, h_i + 2); }