# Cora Lab：`blender-shot-video` 低成本实验报告

## 结论

**有条件通过。** `Yi-111-a/blender-shot-video` 可以承担原 Control Layer 中的单镜头 **Shot Execution Engine**，不值得从零重写 Camera/Blocking/white-model 核心。它已经具备足够清晰的 Shot Spec、固定 LookAt、焦段、简单/多段/跟随运镜、室内空间和代理体约定；本次三版也证明 Camera 参数可独立生效，且相同环境下能像素级稳定复现。

“有条件”是因为当前仓库提交在 Blender 5.2 LTS 上不能原样运行，需要一层很薄的兼容补丁；同时它明确只负责 single-shot，没有 Multi-shot、Continuity 或 Canon 状态。这些应作为外层最小增量，而不是改写白模引擎。

本轮没有调用任何图像或视频生成 API，也没有读取或使用 API key。仓库协议的步骤 ③（首帧）和⑤（成片）均未执行。

## 实验基线

- 公共仓库：`Yi-111-a/blender-shot-video`
- 固定提交：`a7df0518719e0d0ce142c3d45834ff9e0a442ec1`
- 环境：Windows、Blender 5.2.0 LTS
- 场景：6m × 7m × 3.2m 室内实验室、实验桌、Seed Tray、Cora proxy
- 时长与帧率：每版 6 秒、24fps、1280×720、144 帧
- Blocking：三版均为相同的 8 个物体；房间、物体尺寸/位置/旋转和风格字段逐字段一致

## 三个版本

| 版本 | 焦段 | Camera 路径 | 观察结果 |
|---|---:|---|---|
| A | 35mm | Static；`start == end` | 环境中景，实验桌、Cora 和较多房间空间同时可见 |
| B | 50mm | 6 秒内沿 Y 轴缓慢推进 0.8m；sine easing | 首/中/末帧连续靠近；Blocking 不动 |
| C | 85mm | 与 B 完全相同 | 视角明显变窄并压缩构图；因 Camera 位置不自动补偿，Cora 头部被裁切 |

B 与 C 的 `start`、`end`、`lookAt`、duration、fps、easing 完全相同，只有 `lensMm` 不同。A/B/C 的 `room` 和 `objects` 完全相同，因此焦段、Camera 位移和 Blocking 可以独立修改。

## 可复现性

用完全相同的 B Shot Spec 重渲完整 144 帧后，逐帧解码为 RGBA 并计算像素哈希：

- 144/144 帧完全一致
- mismatch count：0
- 代表帧像素哈希前缀：frame 1=`501e7cacab6f27aa`，frame 72=`a71a3c7d30eba5d9`，frame 144=`56841f61b22d3779`

因此，在同一机器、同一 Blender 版本和同一脚本下，本白模流程可稳定复现。跨 Blender 大版本的复现不能直接保证，必须固定运行时或保留兼容测试。

## Blender 5.2 兼容性发现

仓库原脚本在本机不能直接完成渲染，依次遇到以下差异：

1. `Material.use_nodes` 后不再保证存在名为 `Principled BSDF` 的默认节点。
2. World 节点树不再保证存在名为 `Background` 的默认节点。
3. 动画曲线从旧版 `Action.fcurves` 迁移到 layered Action / channelbags。
4. Eevee 引擎标识从脚本写死的 `BLENDER_EEVEE_NEXT` 变为 `BLENDER_EEVEE`。
5. 当前 Blender 构建不接受脚本写死的 FFMPEG 输出；实验改为 PNG 序列后在本地免费编码为 MP4。
6. Windows 后台渲染应传绝对输入/输出路径；相对输出路径会被错误解析到驱动器根目录。

兼容补丁只处理运行时差异和输出封装，没有改变 Shot Spec、Camera 插值、LookAt、Blocking 或白模几何逻辑。见 `blender-5.2-compat.patch`。

## Repo 限制

- **Single-shot only**：没有镜头列表、时间线、镜头衔接或成片拼接状态。
- **没有 Canon/Continuity 模型**：人物、道具和场景只有自由文本名称与坐标，没有稳定 ID、版本、服装状态、道具状态或跨镜头约束。
- **主体动画能力有限**：支持一个 `subject.path` 和 Camera follow；普通 `objects` 是静态的，不适合多角色 blocking 或多个独立运动体。
- **Camera 模型够用但不完整**：没有 sensor size、aperture/DOF、roll、handheld profile、碰撞检测、自动保构图或镜头安全区。85mm 裁切证明焦段会正确生效，但系统不会自动移动 Camera 保持主体完整。
- **灰模可读性有限**：所有占位物共用近似灰色材质；小道具容易融进桌面。本次不得不把 Seed Tray 加厚并轻微旋转，才便于审阅位置。
- **室内灯光写死**：曝光和灰阶对比不足，预览偏暗、噪点明显；它能表达体积和空间，但不是高质量导演预览。
- **缺少正式 schema/validator**：Shot Spec 依赖脚本中的 `get()` 默认值，字段拼错可能被静默忽略或在渲染晚期才暴露。
- **输出依赖 Blender 构建**：编码器能力并不稳定；provider 若要求 H.264，需要在外层规范化转码。
- **最终模型服从度未验证**：本轮按要求没有运行步骤 ③/⑤，因此只能确认 Shot Execution 的免费核心，不能声称任何 AI 视频 provider 会同等服从白模。

## 建议的最小增量

保留本仓库作为不可知 provider 的单镜头执行器，只在外层增加：

1. `scene/sequence manifest`：镜头顺序和每个 Shot Spec 的引用。
2. `canon manifest`：稳定 character/prop/location ID，以及外观和状态版本。
3. `continuity state`：每个镜头进入/退出时的人物位置、朝向、持有物、服装、环境状态。
4. `validator`：生成白模前检查 schema、Canon 引用、相邻镜头状态和 Camera 安全构图。
5. Blender 运行时固定或 CI 兼容矩阵；继续把现有 `build_whitemodel.py` 当执行内核。

这条路线的边界很清楚：**不重写 Control Layer 的执行内核，只补 Multi-shot / Continuity / Canon 的编排与验证层。**

## 交付文件

- 三段式脚本：`breakdown.md`
- Shot Specs：`shot-a-35mm-static.json`、`shot-b-50mm-dolly.json`、`shot-c-85mm-dolly.json`
- 白模视频：`previs-a-35mm-static.mp4`、`previs-b-50mm-dolly.mp4`、`previs-c-85mm-dolly.mp4`
- 审阅帧：`a-start.png`；`b-start.png`、`b-mid.png`、`b-end.png`；`c-start.png`、`c-mid.png`、`c-end.png`
- Blender 5.2 最小兼容补丁：`blender-5.2-compat.patch`

## 强制闸口

当前停在仓库协议的步骤 ④白模审阅。没有用户对 Camera 和 Blocking 的明确批准，不进入任何付费的首帧或最终视频生成步骤。
