关于 dynamic-full-loop
dynamic-full-loop 是用于 Blender 的相机动画技能,通过慢速展示和快速转场呈现产品各个角度,适合制作产品视频。
主要功能
- 01多轴环绕产品拍摄
- 02带速度变化的相机运动
- 03展示前、侧、后、顶部和底部
- 04配置时长、帧率和相机位置
- 05渲染帧并编码视频
适用场景
- 01制作展示产品各个角度的视频
- 02制作营销或社交媒体动态旋转视频
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ kevinbadi/ blender-skills --skill dynamic-full-loop安装后在 Claude Code 中输入/dynamic-full-loop确认已加载。
详细介绍
动态全景循环运镜
摄像机沿多个轴环绕产品,并调整速度:展示产品每一面的过程中采用慢动作,不同面之间则快速甩镜切换。展示正面、侧面、背面、顶部和底部。
适用场景
- 用户希望通过动态运镜“展示每个角度”
- 用户提到“全景循环”“速度渐变”“展示所有侧面”或“动态旋转”
- 社交媒体/营销主视觉视频
参数
| 参数 | 默认值 | 描述 |
|---|---|---|
duration | 10 | 视频时长,单位为秒(由于速度渐变,时长较长) |
fps | 24 | 每秒帧数 |
camera_distance | 4.0 | 摄像机与中心点的距离 |
camera_height | 1.8 | 摄像机高度 |
流程
第 1 步:设置摄像机机架
import bpy, math
bpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))
tgt = bpy.context.active_object
tgt.name = 'DynamicTarget'
bpy.ops.object.camera_add(location=(0, -CAMERA_DISTANCE, CAMERA_HEIGHT))
cam = bpy.context.active_object
cam.name = 'DynamicCam'
cam.data.lens = 45
trk = cam.constraints.new(type='TRACK_TO')
trk.target = tgt
trk.track_axis = 'TRACK_NEGATIVE_Z'
trk.up_axis = 'UP_Y'
# Parent camera to target
bpy.ops.object.select_all(action='DESELECT')
cam.select_set(True)
tgt.select_set(True)
bpy.context.view_layer.objects.active = tgt
bpy.ops.object.parent_set(type='OBJECT', keep_transform=True)
bpy.context.scene.camera = cam
第 2 步:通过速度渐变制作动画
关键在于使用 BEZIER 插值,并让关键帧分布疏密不均,以控制快慢:
- 关键帧间距小、旋转变化幅度小 = 慢速(在某一面前停留)
- 关键帧间距大、旋转变化幅度大 = 快速(甩镜切换)
TOTAL_FRAMES = DURATION * FPS # 240 at 10s/24fps
scene = bpy.context.scene
scene.frame_start = 1
scene.frame_end = TOTAL_FRAMES
scene.render.fps = FPS
# Z rotation (horizontal orbit) - speed ramp pattern
# SLOW on each face, FAST whip between
kf_z = [
(1, 0), # front start
(30, 10), # slow drift on front
(45, 90), # FAST whip to right
(75, 100), # slow on right
(90, 180), # FAST whip to back
(120, 190), # slow on back
(135, 270), # FAST whip to left
(165, 280), # slow on left
(180, 330), # FAST whip toward front
(210, 340), # slow near bottom
(225, 355), # FAST settle
(240, 360), # back to front
]
# X rotation (vertical tilt - over/under)
kf_x = [
(1, 0),
(30, 0),
(75, 15), # slight tilt on right
(120, 0), # level on back
(135, -20), # tilt down on left
(165, -45), # going under
(180, -60), # under/bottom view
(210, -30), # coming back up
(240, 0), # level again
]
for f, d in kf_z:
tgt.rotation_euler[2] = math.radians(d)
tgt.keyframe_insert(data_path='rotation_euler', index=2, frame=f)
for f, d in kf_x:
tgt.rotation_euler[0] = math.radians(d)
tgt.keyframe_insert(data_path='rotation_euler', index=0, frame=f)
# BEZIER interpolation for speed ramp easing
action = tgt.animation_data.action
strip = action.layers[0].strips[0]
for cb in strip.channelbags:
for fc in cb.fcurves:
for kp in fc.keyframe_points:
kp.interpolation = 'BEZIER'
kp.easing = 'AUTO'
第 3 步:渲染并编码
ffmpeg -y -framerate 24 \
-i "~/Desktop/Blender Videos/dynamic_loop_frames/%04d.png" \
-c:v prores_ks -profile:v 4444 -pix_fmt yuva444p10le \
"~/Desktop/Blender Videos/dynamic_full_loop.mov"
备注
- 由于速度渐变需要留出充足时间,这段动画时长较长(10s)
- 如果 Blender 在处理大型网格时卡死,可对已完成的帧进行编码;部分渲染的结果也能使用
- 速度渐变效果来自关键帧间距不均匀的 BEZIER 曲线
评论
支持 Markdown