mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-14 19:27:05 -04:00
Merge main into gpu-resident-effects
This commit is contained in:
commit
f6497177b4
175 files changed
+14942
-811
No files matched your search
@@ -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> {
|
||||
|
||||
@@ -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, ×)
|
||||
}
|
||||
},
|
||||
"ec.time.timewarp" => timewarp(e, ctx, b),
|
||||
_ => None,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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: {}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user