mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-24 10:09:32 -06:00
Composition Settings: the Resolution line shows the frame size the renderer produces (#2167)
This commit is contained in:
@@ -26,9 +26,7 @@ pub(crate) fn render<'g>(e: &mut Enc<'g>, r: &Renderer, comp_id: ItemId, t: Tick
|
||||
return None;
|
||||
}
|
||||
let ctx = r.eval_ctx(comp_id, t)?;
|
||||
let s = r.opts.scale;
|
||||
let w = ((ctx.comp.width as f64 * s).round() as u32).max(1);
|
||||
let h = ((ctx.comp.height as f64 * s).round() as u32).max(1);
|
||||
let (w, h) = effectcraft_render::frame_size(ctx.comp.width, ctx.comp.height, r.opts.scale);
|
||||
if r.depth() > 16 || !e.g.fits(w, h) {
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -1000,8 +1000,7 @@ impl<'a> Renderer<'a> {
|
||||
pub fn comp_frame_cpu(&self, comp_id: ItemId, t: Tick) -> Image {
|
||||
let Some(comp) = self.project.comp(comp_id) else { return Image::new(1, 1) };
|
||||
let s = self.opts.scale;
|
||||
let w = ((comp.width as f64 * s).round() as u32).max(1);
|
||||
let h = ((comp.height as f64 * s).round() as u32).max(1);
|
||||
let (w, h) = frame_size(comp.width, comp.height, s);
|
||||
// Region of interest on a comp with 3D layers: render the frame and crop it. A region
|
||||
// reaching past the comp frame (the Extended Viewer) renders Classic 3D natively — the
|
||||
// planes project through the offset camera — and Advanced 3D as the frame, padded.
|
||||
@@ -2363,6 +2362,12 @@ pub fn extended_region(w: u32, h: u32, visible: [f64; 4], margin: f64) -> Option
|
||||
Some([x0, y0, x1 - x0, y1 - y0])
|
||||
}
|
||||
|
||||
/// The size of a `width` x `height` comp frame rendered at `scale` (both compositors, and the
|
||||
/// frame size Composition Settings shows for a Resolution).
|
||||
pub fn frame_size(width: u32, height: u32, scale: f64) -> (u32, u32) {
|
||||
(((width as f64 * scale).round() as u32).max(1), ((height as f64 * scale).round() as u32).max(1))
|
||||
}
|
||||
|
||||
pub fn render_frame(project: &Project, comp: ItemId, t: Tick, scale: f64) -> Image {
|
||||
Renderer::new(project, &NoFootage, RenderOpts { scale, ..Default::default() }).comp_frame(comp, t)
|
||||
}
|
||||
|
||||
@@ -512,11 +512,10 @@ pub fn params(d: &CompDraft) -> serde_json::Value {
|
||||
})
|
||||
}
|
||||
|
||||
/// The frame size the comp renders at `res`: every n-th pixel, a partial one counted (Auto
|
||||
/// follows the magnification, so the dialog shows the full frame for it).
|
||||
/// The frame size the comp renders at `res` (Auto follows the magnification, so the dialog shows
|
||||
/// the full frame for it).
|
||||
pub fn frame_at(w: u32, h: u32, res: Resolution) -> (u32, u32) {
|
||||
let n = u32::from(res.factor().unwrap_or(1).max(1));
|
||||
(w.div_ceil(n), h.div_ceil(n))
|
||||
effectcraft_render::frame_size(w, h, 1.0 / f64::from(res.factor().unwrap_or(1).max(1)))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -525,9 +524,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn frame_size_follows_the_resolution() {
|
||||
assert_eq!(frame_at(1920, 1081, Resolution::Half), (960, 541), "an odd side keeps its last pixel");
|
||||
assert_eq!(frame_at(1920, 1080, Resolution::Third), (640, 360));
|
||||
assert_eq!(frame_at(1920, 1080, Resolution::Custom(7)), (275, 155));
|
||||
// The renderer's size, which rounds: 1081 / 3 = 360.33 and 1920 / 7 = 274.3.
|
||||
assert_eq!(frame_at(1920, 1081, Resolution::Third), (640, 360));
|
||||
assert_eq!(frame_at(1920, 1080, Resolution::Custom(7)), (274, 154));
|
||||
assert_eq!(frame_at(1920, 1081, Resolution::Half), (960, 541));
|
||||
assert_eq!(frame_at(1920, 1080, Resolution::Full), (1920, 1080));
|
||||
assert_eq!(frame_at(1920, 1080, Resolution::Auto), (1920, 1080));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user