mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-31 21:48:20 -06:00
Merge #1968: Make Gaussian Blur and Fast Box Blur continuous at small values (#1939) (@MarekSpodBiedry)
This commit is contained in:
@@ -261,6 +261,10 @@ fn gaussian(e: &mut Enc, ctx: &EffectCtx, mut b: GBuf) -> Option<GBuf> {
|
||||
return Some(b);
|
||||
}
|
||||
let (kx, ky) = dims_xy(ctx.params.e("dimensions"));
|
||||
// Small sigmas use the CPU's sampled kernel (#1939).
|
||||
if effectcraft_raster::gaussian_is_exact(s * kx, s * ky) {
|
||||
return None;
|
||||
}
|
||||
let repeat = ctx.params.b("repeatEdge");
|
||||
if !repeat && !ctx.adjustment {
|
||||
b.pad(e, (s * 3.0).ceil() as u32)?;
|
||||
@@ -270,7 +274,12 @@ fn gaussian(e: &mut Enc, ctx: &EffectCtx, mut b: GBuf) -> Option<GBuf> {
|
||||
}
|
||||
|
||||
fn box_blur(e: &mut Enc, ctx: &EffectCtx, mut b: GBuf) -> Option<GBuf> {
|
||||
let r = (ctx.params.f("radius") * b.scale).round().max(0.0) as usize;
|
||||
let radius = (ctx.params.f("radius") * b.scale).max(0.0);
|
||||
// Fractional radii blend two integer radii on the CPU (#1939).
|
||||
if radius - radius.floor() >= 1e-4 {
|
||||
return None;
|
||||
}
|
||||
let r = radius.floor() as usize;
|
||||
if r == 0 {
|
||||
return Some(b);
|
||||
}
|
||||
|
||||
@@ -188,6 +188,10 @@ fn gaussian_legacy(e: &mut Enc, ctx: &EffectCtx, mut b: GBuf) -> Option<GBuf> {
|
||||
2 => (0.0, 1.0),
|
||||
_ => (1.0, 1.0),
|
||||
};
|
||||
// Small sigmas use the CPU's sampled kernel (#1939).
|
||||
if effectcraft_raster::gaussian_is_exact(s * kx, s * ky) {
|
||||
return None;
|
||||
}
|
||||
if !ctx.adjustment {
|
||||
b.pad(e, (s * 3.0).ceil() as u32)?;
|
||||
}
|
||||
|
||||
+19
-4
@@ -524,12 +524,27 @@ pub(crate) fn c(r: f64, g: f64, b: f64) -> Value {
|
||||
Value::Color([r, g, b, 1.0])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn small_blurs_fall_back_to_the_cpu() {
|
||||
// #1939: small Gaussian sigmas and fractional box radii render on the CPU kernel.
|
||||
for (id, vals) in [("ec.blur.gaussian", [("blurriness", n(0.9))]), ("ec.blur.fastbox", [("radius", n(1.5))])] {
|
||||
let mut s = Scene::new(BitDepth::Bpc32);
|
||||
let bg = s.solid([0.15, 0.1, 0.2], 97, 61);
|
||||
s.push(bg);
|
||||
let mut l = s.footage(70, 44);
|
||||
s.effect(&mut l, id, &vals);
|
||||
s.push(l);
|
||||
check(&format!("{id} {vals:?}"), compare_at(&s, opts(), Tick::ZERO), 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gpu_effects_match_cpu() {
|
||||
effect_case("ec.blur.gaussian", &[("blurriness", n(9.0))]);
|
||||
effect_case("ec.blur.gaussian", &[("blurriness", n(4.0)), ("dimensions", Value::Enum(1)), ("repeatEdge", Value::Bool(true))]);
|
||||
effect_case("ec.blur.fastbox", &[("radius", n(5.0)), ("iterations", n(2.0))]);
|
||||
effect_case("ec.blur.fastbox", &[("radius", n(3.0)), ("dimensions", Value::Enum(2)), ("repeatEdge", Value::Bool(true))]);
|
||||
// Sigma 3 px and up and even radii, so the half-scale pass stays on the GPU too (#1939).
|
||||
effect_case("ec.blur.gaussian", &[("blurriness", n(14.0))]);
|
||||
effect_case("ec.blur.gaussian", &[("blurriness", n(12.0)), ("dimensions", Value::Enum(1)), ("repeatEdge", Value::Bool(true))]);
|
||||
effect_case("ec.blur.fastbox", &[("radius", n(6.0)), ("iterations", n(2.0))]);
|
||||
effect_case("ec.blur.fastbox", &[("radius", n(4.0)), ("dimensions", Value::Enum(2)), ("repeatEdge", Value::Bool(true))]);
|
||||
effect_case("ec.blur.directional", &[("direction", n(30.0)), ("length", n(12.0))]);
|
||||
effect_case("ec.stylize.glow", &[("threshold", n(40.0)), ("radius", n(14.0)), ("intensity", n(1.5))]);
|
||||
effect_case("ec.stylize.glow", &[("colors", Value::Enum(1)), ("operation", Value::Enum(1)), ("colorA", c(1.0, 0.8, 0.1))]);
|
||||
|
||||
@@ -46,6 +46,7 @@ fn bevels_and_legacy_gaussian() {
|
||||
effect_case("ec.perspective.bevelalpha", &[("edgeThickness", n(2.0)), ("lightAngle", n(200.0)), ("lightColor", c(1.0, 0.8, 0.5))]);
|
||||
effect_case("ec.perspective.beveledges", &[("edgeThickness", n(0.1)), ("lightIntensity", n(0.5))]);
|
||||
effect_case("ec.perspective.beveledges", &[("edgeThickness", n(0.3)), ("lightAngle", n(130.0))]);
|
||||
effect_case("ec.obsolete.gaussianlegacy", &[("blurriness", n(7.0))]);
|
||||
effect_case("ec.obsolete.gaussianlegacy", &[("blurriness", n(5.0)), ("blurDimensions", e(2))]);
|
||||
// Sigma 3 px and up at half scale too: smaller ones render on the CPU (#1939).
|
||||
effect_case("ec.obsolete.gaussianlegacy", &[("blurriness", n(14.0))]);
|
||||
effect_case("ec.obsolete.gaussianlegacy", &[("blurriness", n(12.0)), ("blurDimensions", e(2))]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user