Fix T88849: Motion blur in cycles leaves bright edge on trailing end of blur

The code that computes and inverts the shutter CDF had some issues that caused
the result to be asymmetric, this tweaks it to be more robust and produce
symmetric outputs for symmetric inputs.
This commit is contained in:
Lukas Stockner 2023-01-09 03:05:57 +01:00
parent e7a554e551
commit 95696d09bc
Notes: blender-bot 2023-02-14 01:21:16 +01:00
Referenced by issue #88849, Motion blur in cycles leaves bright edge on trailing end of blur.
3 changed files with 8 additions and 5 deletions

View File

@ -32,7 +32,7 @@ static float shutter_curve_eval(float x, array<float> &shutter_curve)
return 1.0f;
}
x *= shutter_curve.size();
x = saturatef(x) * shutter_curve.size() - 1;
int index = (int)x;
float frac = x - index;
if (index < shutter_curve.size() - 1) {

View File

@ -16,6 +16,7 @@ void util_cdf_invert(const int resolution,
const bool make_symmetric,
vector<float> &inv_cdf)
{
assert(cdf[0] == 0.0f && cdf[resolution] == 1.0f);
const float inv_resolution = 1.0f / (float)resolution;
const float range = to - from;
inv_cdf.resize(resolution);
@ -39,8 +40,8 @@ void util_cdf_invert(const int resolution,
}
else {
for (int i = 0; i < resolution; i++) {
float x = from + range * (float)i * inv_resolution;
int index = upper_bound(cdf.begin(), cdf.end(), x) - cdf.begin();
float x = (i + 0.5f) * inv_resolution;
int index = upper_bound(cdf.begin(), cdf.end(), x) - cdf.begin() - 1;
float t;
if (index < cdf.size() - 1) {
t = (x - cdf[index]) / (cdf[index + 1] - cdf[index]);
@ -49,7 +50,7 @@ void util_cdf_invert(const int resolution,
t = 0.0f;
index = resolution;
}
inv_cdf[i] = (index + t) * inv_resolution;
inv_cdf[i] = from + range * (index + t) * inv_resolution;
}
}
}

View File

@ -26,9 +26,11 @@ void util_cdf_evaluate(
cdf[i + 1] = cdf[i] + fabsf(y);
}
/* Normalize the CDF. */
float fac = (cdf[resolution] == 0.0f) ? 0.0f : 1.0f / cdf[resolution];
for (int i = 0; i <= resolution; i++) {
cdf[i] /= cdf[resolution];
cdf[i] *= fac;
}
cdf[resolution] = 1.0f;
}
/* Invert pre-calculated CDF function. */