mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-30 13:08:07 -06:00
fix: progressive blur holds two levels at a time, not every level (#2092 review follow-up)
This commit is contained in:
@@ -289,16 +289,24 @@ pub fn progressive_blur(img: &Image, iris: &Iris, radius: &[f32]) -> Image {
|
||||
return bokeh_blur(img, iris, levels[0] as f64);
|
||||
}
|
||||
let (lo, hi, n) = (levels[0], levels[levels.len() - 1], levels.len());
|
||||
let blurred: Vec<Image> = levels.par_iter().map(|&r| bokeh_blur(img, iris, r as f64)).collect();
|
||||
// A pixel blends only the two levels around its radius, so the levels are made in order and
|
||||
// only that pair is held: peak memory stays a few images whatever the level count, rather
|
||||
// than one image per level. Each level's blur is parallel over its rows.
|
||||
let mut out = Image::new(img.width, img.height);
|
||||
out.data.par_iter_mut().enumerate().for_each(|(i, o)| {
|
||||
let r = radius[i];
|
||||
let f = ((r - lo) / (hi - lo) * (n - 1) as f32).clamp(0.0, (n - 1) as f32);
|
||||
let k = (f.floor() as usize).min(n - 2);
|
||||
let t = f - k as f32;
|
||||
let (a, b) = (blurred[k].data[i], blurred[k + 1].data[i]);
|
||||
*o = [0, 1, 2, 3].map(|c| a[c] + (b[c] - a[c]) * t);
|
||||
});
|
||||
let mut below = bokeh_blur(img, iris, lo as f64);
|
||||
for (k, &r) in levels.iter().enumerate().skip(1) {
|
||||
let above = bokeh_blur(img, iris, r as f64);
|
||||
out.data.par_iter_mut().enumerate().for_each(|(i, o)| {
|
||||
let f = ((radius[i] - lo) / (hi - lo) * (n - 1) as f32).clamp(0.0, (n - 1) as f32);
|
||||
let kk = (f.floor() as usize).min(n - 2);
|
||||
if kk + 1 == k {
|
||||
let t = f - kk as f32;
|
||||
let (a, b) = (below.data[i], above.data[i]);
|
||||
*o = [0, 1, 2, 3].map(|c| a[c] + (b[c] - a[c]) * t);
|
||||
}
|
||||
});
|
||||
below = above;
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
|
||||
@@ -294,8 +294,10 @@ fn dof_radii(cam: &CameraState, dof: &super::camera::Dof, world: Mat4, buf: &Buf
|
||||
}
|
||||
|
||||
/// Pixels a padded blur buffer may have: the ~16 million layer buffers are held to
|
||||
/// ([`crate::Renderer::raster_scale`]), so a blur never needs more memory than a large layer;
|
||||
/// twice the buffer when that is larger, so a big buffer can still be blurred.
|
||||
/// ([`crate::Renderer::raster_scale`]), or twice the buffer when that is larger, so a big buffer
|
||||
/// can still be blurred. The blur holds a few images of this size at once whatever its level
|
||||
/// count ([`super::bokeh::progressive_blur`]), so blurring a small plane costs no more memory than
|
||||
/// blurring a large layer.
|
||||
const DOF_PAD_BUDGET: f64 = 16.0e6;
|
||||
|
||||
/// Comp pixels per buffer pixel below which a plane isn't blurred. Such a plane covers almost no
|
||||
|
||||
Reference in New Issue
Block a user