Merge main into gpu-resident-effects

This commit is contained in:
Matej Kozlovský committed 2026-10-12 12:41:40 +02:00
commit f6497177b4
175 files changed
+14942 -811

No files matched your search

+15
View File
@@ -145,6 +145,21 @@ impl effectcraft_render::FxTarget for GpuFx<'_, '_> {
let out = f(Buf { img, offset: b.offset, scale: b.scale });
self.b = self.e.g.upload_image(&out.img).map(|img| GBuf { img, offset: out.offset, scale: out.scale });
}
/// GBuf::cover, like `pad`: a bigger texture with the old one copied into place, no
/// readback. A region the device can't allocate leaves the buffer as it is.
fn cover(&mut self, size: [f64; 2]) {
let Some(b) = self.b.take() else { return };
let out = match effectcraft_effects::cover_plan(b.offset, b.scale, size, b.img.width, b.img.height) {
Some((dx, dy, w, h)) if self.e.g.fits(w, h) => {
let img = self.e.image(w, h);
self.e.copy_into(&b.img, &img, dx, dy);
GBuf { img, offset: [b.offset[0] + dx as f64, b.offset[1] + dy as f64], scale: b.scale }
}
_ => b,
};
self.b = Some(out);
}
}
fn apply(e: &mut Enc, id: &str, ctx: &EffectCtx, b: GBuf) -> Option<GBuf> {
+9 -3
View File
@@ -45,11 +45,17 @@ pub(crate) fn apply(e: &mut Enc, id: &str, ctx: &EffectCtx, b: GBuf) -> Option<G
let fd = 1.0 / ctx.fps();
mean_of(e, ctx, b, &(-back..=fwd).map(|k| ctx.time + k as f64 * fd).collect::<Vec<_>>())
}
// Pixel Motion Blur synthesizes along measured motion vectors (#535); a plan that
// cannot be built (no host) declines to the CPU effect.
// Pixel Motion Blur synthesizes along measured motion vectors (#535); without a plan (no
// host to read neighbouring frames) it averages the shutter's frames, as the CPU effect does.
"ec.time.pixelmotionblur" => match effectcraft_effects::pmb_plan(ctx) {
Some(plan) => render_plan(e, &plan),
None => None,
None => {
let angle = if ctx.params.e("shutterControl") == 1 { ctx.params.f("shutterAngle") } else { 180.0 };
let n = ctx.params.f("shutterSamples").round().clamp(1.0, 64.0) as usize;
let span = angle.clamp(0.0, 720.0) / 360.0 / ctx.fps();
let times: Vec<f64> = (0..n).map(|i| ctx.time - span * 0.5 + if n > 1 { span * i as f64 / (n - 1) as f64 } else { span * 0.5 }).collect();
mean_of(e, ctx, b, &times)
}
},
"ec.time.timewarp" => timewarp(e, ctx, b),
_ => None,
+1 -1
View File
@@ -665,7 +665,7 @@ fn fxn_fractal(@builtin(global_invocation_id) gid: vec3<u32>) {
r = blend_pixel(P.u[2].x, orig, s, 0.5);
}
let bo = P.f[1].w;
textureStore(out, p, orig * bo + r * (1.0 - bo));
textureStore(out, p, orig * bo + r * orig.a * (1.0 - bo));
}
// ---------------------------------------------------------------- Noise Alpha / Noise HLS (noise.rs)
+5 -5
View File
@@ -865,13 +865,13 @@ fn pointwise(@builtin(global_invocation_id) gid: vec3<u32>) {
val = 1.0 - val;
}
let op = P.f[2].z;
var fx = vec4<f32>(vec3<f32>(val) * op, op);
if (P.u[1].z == 1u) {
// Normal: the noise over the layer at Opacity, then Blend With Original.
let over = vec4<f32>(vec3<f32>(val) * op, op) + px * (1.0 - op);
px = px * P.f[2].y + over * (1.0 - P.f[2].y);
} else {
px = put(px, vec3<f32>(val), op, P.f[2].y);
// Normal: the noise over the layer at Opacity.
fx = fx + px * (1.0 - op);
}
// Inside the layer's alpha (its masks), then Blend With Original.
px = px * P.f[2].y + fx * px.w * (1.0 - P.f[2].y);
}
default: {}
}