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.
This commit is contained in:
u3dreal
2025-10-16 15:38:38 +02:00
committed by Lukas Stockner
parent c22db2251e
commit b597c0f1ed

View File

@@ -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);
}