fix: cinematic camera accounts for output aspect ratio
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) <noreply@anthropic.com>
This commit is contained in:
@@ -321,14 +321,21 @@ def _get_segment_params(frame: int, bsphere_radius: float):
|
|||||||
return azimuth, elevation, distance, lens, use_dof
|
return azimuth, elevation, distance, lens, use_dof
|
||||||
|
|
||||||
|
|
||||||
def _setup_cinematic_camera(parts, bbox_center, bsphere_radius, total_frames):
|
def _setup_cinematic_camera(parts, bbox_center, bsphere_radius, total_frames, width=1920, height=1080):
|
||||||
"""Create camera and keyframe the cinematic 4-segment animation.
|
"""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.
|
Returns the camera object.
|
||||||
"""
|
"""
|
||||||
# Starting azimuth: offset so segment 1 starts from a good angle (40deg)
|
# Starting azimuth: offset so segment 1 starts from a good angle (40deg)
|
||||||
base_azimuth = 40.0
|
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
|
# Create camera
|
||||||
start_az, start_el, start_dist, start_lens, _ = _get_segment_params(1, bsphere_radius)
|
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)
|
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)
|
bpy.context.scene.frame_set(frame)
|
||||||
|
|
||||||
azimuth, elevation, distance, lens, use_dof = _get_segment_params(frame, bsphere_radius)
|
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
|
azimuth += base_azimuth # offset from base viewing angle
|
||||||
|
|
||||||
# Camera position from spherical coordinates
|
# Camera position from spherical coordinates
|
||||||
@@ -746,7 +754,7 @@ def main():
|
|||||||
scene.frame_start = 1
|
scene.frame_start = 1
|
||||||
scene.frame_end = frame_count
|
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 ────────────────────────────────────────────────────
|
# ── Colour management ────────────────────────────────────────────────────
|
||||||
if not use_template:
|
if not use_template:
|
||||||
|
|||||||
Reference in New Issue
Block a user