From 02669c395c73c13bd2d366583cd6290e1b702c17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hartmut=20N=C3=B6renberg?= Date: Mon, 16 Mar 2026 08:15:10 +0100 Subject: [PATCH] fix: cinematic camera accounts for output aspect ratio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For 16:9 (1280x720), vertical FOV is narrower than horizontal — products could be clipped top/bottom. Now applies an aspect ratio correction factor to camera distance: wider formats push camera further back proportionally. Still render (_blender_camera.py) already handled this via min(fov_h, fov_v); cinematic now has equivalent correction. Co-Authored-By: Claude Opus 4.6 (1M context) --- render-worker/scripts/cinematic_render.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/render-worker/scripts/cinematic_render.py b/render-worker/scripts/cinematic_render.py index 334014a..55cee72 100644 --- a/render-worker/scripts/cinematic_render.py +++ b/render-worker/scripts/cinematic_render.py @@ -321,14 +321,21 @@ def _get_segment_params(frame: int, bsphere_radius: float): return azimuth, elevation, distance, lens, use_dof -def _setup_cinematic_camera(parts, bbox_center, bsphere_radius, total_frames): - """Create camera and keyframe the cinematic 4-segment animation. +def _setup_cinematic_camera(parts, bbox_center, bsphere_radius, total_frames, width=1920, height=1080): + """Create camera and keyframe the cinematic animation. + + Takes aspect ratio into account — wider formats push the camera + further back so the product isn't clipped vertically. Returns the camera object. """ # Starting azimuth: offset so segment 1 starts from a good angle (40deg) base_azimuth = 40.0 + # Aspect ratio correction: for wide formats (16:9), vertical FOV is tighter + # so we need more distance. For square/portrait, no correction needed. + aspect_correction = max(1.0, (width / height) * 0.7) if height > 0 else 1.0 + # Create camera start_az, start_el, start_dist, start_lens, _ = _get_segment_params(1, bsphere_radius) start_pos = _spherical_to_xyz(base_azimuth + start_az, start_el, start_dist, bbox_center) @@ -354,6 +361,7 @@ def _setup_cinematic_camera(parts, bbox_center, bsphere_radius, total_frames): bpy.context.scene.frame_set(frame) azimuth, elevation, distance, lens, use_dof = _get_segment_params(frame, bsphere_radius) + distance *= aspect_correction # scale for aspect ratio azimuth += base_azimuth # offset from base viewing angle # Camera position from spherical coordinates @@ -746,7 +754,7 @@ def main(): scene.frame_start = 1 scene.frame_end = frame_count - camera = _setup_cinematic_camera(parts, bbox_center, bsphere_radius, frame_count) + camera = _setup_cinematic_camera(parts, bbox_center, bsphere_radius, frame_count, width, height) # ── Colour management ──────────────────────────────────────────────────── if not use_template: