diff --git a/AGENTS.md b/AGENTS.md index 11d90e8..9987d85 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -116,7 +116,7 @@ effort 管 agent 自己查得多细,导演模式管人拍板哪些事,两个 | 3 分钟以上的长片,或靠故事、谜题推进的片子(角色短片、长讲解) | 主类型文档,加上 `playbook/09-narrative.md`(骨架、节拍表、张力曲线、换挡) | 按主类型 | — | | 要发短视频平台:开头钩子、标题、封面 | `playbook/10-hooks-and-packaging.md`,加上主类型文档 | 按主类型 | — | | 要写有篇章、有主题的配乐(MV、介绍片和发布片、45 s 以上靠音乐撑起结构的片子、`studio` 档位,或者人要亲自定主题和 BGM) | `playbook/11-composition.md`;`score.json` 的写法见 `playbook/04-audio.md` | `bin/vh music` | — | -| 3D 场景、着色器短片(Three.js) | 暂无专门的类型文档:以 `03-product-promo.md` 的运动规则为准,加上 `playbook/08-vfx-and-motion-sources.md`(一镜到底、特效预设栈、子帧运动模糊)。要路径追踪的光影(玻璃、皮肤、体积光)、物理模拟或真实景深时,读 `engines/blender.md`(实验性:维护者的 Mac 没装 Blender,没验证过,渲染时间先渲 5 帧校准) | HyperFrames + Three.js 层;重光影的镜头用 Blender | `showcase/04-intro-film/`、`cases/opus55-gallery.md` 的 3D 一节和第 6 节(Austerlitz 长片深读) | +| 3D 场景、着色器短片(Three.js) | 暂无专门的类型文档:以 `03-product-promo.md` 的运动规则为准,加上 `playbook/08-vfx-and-motion-sources.md`(一镜到底、特效预设栈、子帧运动模糊)。要路径追踪的光影(玻璃、皮肤、体积光)、物理模拟或真实景深时,读 `engines/blender.md`(部分验证:风格样片 `tabletop-miniature` 已用 Blender 5.2.2 渲染,项目用的命令还有几条没跑过;渲染时间先渲 3–5 帧校准) | HyperFrames + Three.js 层;重光影的镜头用 Blender | `showcase/04-intro-film/`、`cases/opus55-gallery.md` 的 3D 一节和第 6 节(Austerlitz 长片深读) | | 想要新点子、立意,一句话需求想做得出彩,或者不想千篇一律 | `playbook/12-ideation.md`,再加主类型文档 | 按主类型 | `cases/oneshot-five.md`、`cases/explainer-interstellar-blackhole.md` | | 想要某种风格、参考某部名作,或者不想每支片子都一个口味 | `styles/README.md`,再读选中预设的 `styles//STYLE.md` | 随主引擎 | 每个预设的 `media/swatch.mp4`,总览 `styles/gallery.jpg` | | 想知道某种镜头怎么动(开场、字卡、转场、卡点、收尾),或想要"专业的节奏" | `recipes/README.md`,再读 `recipes/sequences/` 里合适的骨架 | 随主引擎 | `cases/promo-video-shotcraft.md` | diff --git a/CHANGELOG.md b/CHANGELOG.md index dd18f20..2ff1690 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,61 @@ ## Unreleased +**Style swatches can be Blender scenes; a 29th style, tabletop-miniature (桌面微缩剧场)** +- Why: every swatch is drawn on a canvas, and none looks like a lit, physical set. Taking apart a community film (Kevin Ngo's piano short, made with Python and rendered in Blender) gave a stop-motion miniature grammar whose look rests on path-traced light and real depth of field, so the swatch renderer needed a Blender path. Blender 5.2.2 is now installed on the maintainer's Mac. +- `styles/_swatch/`: a style folder with `swatch.py` instead of `swatch.js` renders in Blender (Cycles). `blender_render.py` runs the scene's `build(env)` once per process and `apply(t, env)` before every frame, setting properties directly (no keyframes, no handlers, so no motion blur, which suits stop-motion). It writes PNG frames, and `render.sh` encodes them into the same 1080p BT.709 `hf.mp4` the HyperFrames path makes, so the frame checks, music, foley, mix, `bin/vh qa`, encode, poster and contact sheet are shared. New `render.sh` options for Blender scenes: `--frames 149,90,12` (with `--png`: only those frames, in that order) and `--stamp`. +- Final renders use Cycles on the CPU. Measured on an M3 Max: the same frame rendered twice is pixel-identical on the CPU, but not on Metal (92 dB) or EEVEE (85 dB), and this pipeline's CRF-to-size loop amplifies small differences. `--draft` uses the GPU. tabletop-miniature: about 15 s per frame on the CPU at 32 spp + OIDN (64 spp looked the same side by side), about 1.6 s on Metal. +- Safety, following `engines/blender.md`, in three layers; the third is the boundary: + - `blender_prep.py scan` reads `swatch.py` as a syntax tree before anything runs it. It is a lint that catches mistakes and the plain ways out, not a wall. Imports are allow-listed (`bpy bmesh mathutils math colorsys json sys`, so no `random` or `time` either; of `json` only `dumps`/`loads`, of `sys` only `argv`). Names and attributes starting with `_` and strings containing `__` are refused, which closes the dunder routes an independent reviewer found (`bpy.utils._os`, `x.__dict__["__import__"]`). So are `eval exec compile open getattr setattr type dir globals vars`, and bpy that loads, saves or runs anything (.blend files, text blocks, drivers, `bpy.utils`, `save_render`, handlers, timers). `foley.mjs` runs the same scan before it reads `FOLEY`, and on macOS reads it inside its own sandbox. + - Blender runs under `env -i` (no API keys), with its HOME and TMPDIR in `out//.blender/`. + - On macOS, under `sandbox-exec`: no network, no handing URLs or Apple events to other apps, writes only to `out//` and Blender's own subfolder of the per-user cache (Metal keeps compiled shaders there; denied, every frame recompiles, 13 s instead of 2 s). Final (CPU) renders also cannot read the home folder except the repo, Blender and `~/Library/Fonts`; frame 90 rendered under it is pixel-identical to the frame rendered without it. Drafts on Metal cannot take that rule: Metal crashes loading cached kernels when the home folder is unreadable. Linux has no sandbox, so render only scenes you have read. + - A cold Metal kernel compile is silent for about 110 s, so the watchdog's stall limit for Blender scenes is 300 s. The `--python-exit-code 1` runs are started with job control off, so the watchdog's process-group kill reaches them; with it on, the Blenders landed in their own groups. When one of several workers fails, the others are stopped. +- Fonts: a scene's `FONTS` are fontconfig patterns; `blender_prep.py fonts` resolves them with `fc-match` to the same system fonts `fonts.css` uses, and stops the render when the match is another family (a Chinese role on a Latin font prints tofu). Blender loads only face 0 of a `.ttc`, so another face (Songti SC Bold is face 1) is written out with fontTools to `out//fonts/` on every run, atomically, a local copy that is never committed. +- `determinism.sh` on a Blender scene re-renders 12 frames spread over the clip, last to first, in 3 fresh Blender processes and compares them pixel by pixel with the final render's frames (`out//frames/`, used when their `inputs.txt` stamp still matches: the Blender version, every file in the style folder except `media/`, docs and audio, and the two renderer scripts, taken when the render starts; otherwise it renders all frames in order first and keeps them there). It earned its place on the first final render: with `render.use_persistent_data` on, Cycles on the CPU rendered the teacup black on frames 27–44 of the in-order render and grey when those frames were rendered alone, and the check failed on frame 30 (24.5 dB). The renderer now keeps persistent data off (per-frame time barely changed, 15–19 s). `foley.mjs` reads `FOLEY` from `swatch.py` (after the scan). `bin/vh style` skips the HyperFrames install for a Blender scene. +- Licence (the maintainer's decision, 2026-10-01): files that import bpy are GPL-3.0-or-later with an SPDX header, as Blender asks of published bpy scripts: `styles/_swatch/blender_render.py` and `styles/tabletop-miniature/swatch.py`. The rest of the repo stays MIT. Both READMEs' licence sections and `engines/blender.md` ("许可证") say so. `tools/ci.sh` runs the scan on every `styles/*/swatch.py` and fails a `.py` that imports bpy without the header. +- The style (`styles/tabletop-miniature/`): + - Learned from Aardman's *A Grand Day Out* (1989), Laika's *Coraline* (2009), Olivo Barbieri's tilt-shift *Site Specific* series and the piano film. + - The grammar: + - a real-scale tabletop, with a geometric puppet that acts with its gait and two bead eyes; + - only practical light, whose colour and angle carry time; + - the camera at the puppet's eye height, f/4.5, so only a few millimetres are sharp; + - puppets on twos with a hand-placed jitter, camera and lights on ones, no motion blur; + - one acoustic instrument, with each action a note. + - The swatch: the camera starts tight on a sleeping felt puck. The desk lamp clicks on, the puck wakes, the camera pulls back and the blocks slide in, and once the camera has slowed a playbill card is lowered on two threads. The puck walks to three wooden blocks and hops up them: 大纲 is raw wood, 分镜 is half-dipped in red, 初版 is all red, so the paint is the progress. For its payoff the camera cranes up to the puck's eye height and swings round the set, bringing the window in behind it. The lamp goes off on the last downbeat and the puck flinches; the camera drifts on through the dark, the morning comes through the window behind it, and the puck falls asleep. The puppet is on ones while the camera follows it: on twos it stepped back 8–16 px on every odd frame. + - The score is one upright piano: the low register pedalled underneath, a note on each takeoff and a dry high note on each landing, and a V7 chord held through the dark until dawn resolves it. Seven foley sounds are synthesized in `custom_sfx.py`: lamp switch on and off, felt on wood ×3, the thread pulled tight, a bird. + - Its layout was checked frame by frame with a pinhole projection before rendering: the hanging card clears the highest hop by 20 px. + - Seven rounds of independent "harsh motion director" review on fresh contexts, with the worst issues fixed between rounds. The lowest score was 6 in the first round and 7 in every round after; no round had all seven dimensions at 8 or above (the score had seven dimensions then; 立意 came later). Scores below are hook, phone, motion, variety, polish, accuracy, sync. + - Round 4 (8, 8, 7, 8, 7, 8, 9), then fixed: + - the last hop moved to ones (it had 3 air drawings on twos); + - a cool moonlight fill and a dark window frame were added, because the blackout had pure-black blocks while the frame glowed; + - a half-lid and a nod come before sleep. + - Round 5 (8, 8, 7, 8, 8, 9, 9), then fixed: + - the small hop on 初版 was one airborne pose held for 4 frames; it is now a crouch, rise, apex and fall; + - nothing moved in the dark: the puck now flinches at the lamp-off, and the camera keeps drifting and hands over to the dawn move at the same speed; + - the title card and the blocks arrived in the same 0.6 s, and the 大纲 label sat cut by the frame edge for 0.4 s: the opening now starts with the blocks out of frame, and the card comes in once the pull-back has slowed; + - the moonlight fill is brighter (初版 at night 1.6:1 → 2.1:1). + - Round 6 (8, 8, 8, 7, 7, 9, 9), then fixed: + - the payoff played in the same wide shot: the camera now cranes up to the puck's eye height and swings round the set, bringing the window in behind it (a push-in was not possible with the title and all three labels kept inside the safe area); + - the stitched "^ ^" eyes were flat arcs that floated off the round face and showed past its edge as it turned; they now lie on the surface; + - the moon's glint on the varnished desk was the brightest thing in the frame (luma 236, the title card 184): the moon now sits higher and the glint mostly falls below the frame (178). + - Round 7, the version shipped here (8, 8, 8, 7, 8, 9, 8). What it found, not fixed: + - variety: the swing round the set moves the background more than the set, so 3.0, 4.0 and 5.0 s read as one composition. Its suggestion is to push in at the lamp-off and end on a medium close-up of the puck against the morning window, at the cost of the title leaving the frame; + - the blocks are on screen from 0.5 s, before the title, rather than arriving in the 2.0–4.0 s motif window (counted as a deviation from the content spec since round 5); + - light: until the lamp goes off, the desk glint is still the brightest thing in the lower half; a strip beside 初版 clips to white at dawn; in moonlight 初版 drops to about 2.3:1; + - sound: the "air" riser starts when the dawn is already mostly up, and the bird sits under the piano. +- `engines/blender.md` changes from "experimental, never run" to "partly verified". The first-smoke items that were run are written back as 【实测 5.2.2】: + - render repeatability by device; + - speeds; + - what `sandbox-exec` must allow; + - the `.ttc` face limit; + - Mix-node socket identifiers; + - dynamic `view_transform` enums; + - stdout buffering in background mode; + - job control. + + `engines/README.md` and `CLAUDE.md` (and `AGENTS.md`) now point to the working swatch path. +- Docs: `styles/README.md` (table row, sound row, how to add a Blender style), `styles/_swatch/README.md` ("Blender 场景"), both READMEs (29 styles). The gallery is rebuilt with the new poster and clip. + **Research note 06: concept-first against floors only, and two self-checks for quick** - `docs/research/06-concept-first-ab.md` (and `en/`): two arms, two requests (a 30 s Milky Way explainer, a 20 s bakery opening, both silent), four films by the same model, scored blind by a fresh reviewer on the eight dimensions. Both times the reviewer found the workflow's film more original (concept 7 vs 6, 8 vs 7) and chose the floors-only film to post; the means differ by 0.3 and 0.7, likely within run-to-run noise, so the pairwise choices are what the note reads. Its reasons: labels sitting exactly at the 44 px floor, about 8 px on a phone, and a key transformation done as a dissolve. Slowness does not explain it: measured the same way (frame differences), both arms are about as still (opposite ways in the two pairs); arm B's stillness starts at the very beginning, but the hook scores do not tie that to the result. In one pair (Milky Way, 8/10 similar) the model reached much the same idea without the workflow. All four hooks scored 3–5; time and tokens about equal. Figure: five frames per film. - Changes it led to: the quick card's self-check (and `playbook/02`'s effort note) adds a phone-size contact sheet and a first-2 s strip, with the strip command and what 44 px becomes on a phone; `playbook/12-ideation.md` §6 says readouts people must read should not sit at the floor; the digital-silence floor says it applies to films with sound (CLAUDE.md, playbook 12, TASTE_CHECKLIST #18), which both workflow agents had to reason out; type 02's caption weight falls back to the local font's heaviest; type 03's checks add searching a fictional brand name for a real one (one film named its bakery 一条, a known brand). Open: whether the 44 px floor, written for 1080 wide, should scale for landscape. diff --git a/CLAUDE.md b/CLAUDE.md index 450d305..b69b697 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -113,7 +113,7 @@ effort 管 agent 自己查得多细,导演模式管人拍板哪些事,两个 | 3 分钟以上的长片,或靠故事、谜题推进的片子(角色短片、长讲解) | 主类型文档,加上 `playbook/09-narrative.md`(骨架、节拍表、张力曲线、换挡) | 按主类型 | — | | 要发短视频平台:开头钩子、标题、封面 | `playbook/10-hooks-and-packaging.md`,加上主类型文档 | 按主类型 | — | | 要写有篇章、有主题的配乐(MV、介绍片和发布片、45 s 以上靠音乐撑起结构的片子、`studio` 档位,或者人要亲自定主题和 BGM) | `playbook/11-composition.md`;`score.json` 的写法见 `playbook/04-audio.md` | `bin/vh music` | — | -| 3D 场景、着色器短片(Three.js) | 暂无专门的类型文档:以 `03-product-promo.md` 的运动规则为准,加上 `playbook/08-vfx-and-motion-sources.md`(一镜到底、特效预设栈、子帧运动模糊)。要路径追踪的光影(玻璃、皮肤、体积光)、物理模拟或真实景深时,读 `engines/blender.md`(实验性:维护者的 Mac 没装 Blender,没验证过,渲染时间先渲 5 帧校准) | HyperFrames + Three.js 层;重光影的镜头用 Blender | `showcase/04-intro-film/`、`cases/opus55-gallery.md` 的 3D 一节和第 6 节(Austerlitz 长片深读) | +| 3D 场景、着色器短片(Three.js) | 暂无专门的类型文档:以 `03-product-promo.md` 的运动规则为准,加上 `playbook/08-vfx-and-motion-sources.md`(一镜到底、特效预设栈、子帧运动模糊)。要路径追踪的光影(玻璃、皮肤、体积光)、物理模拟或真实景深时,读 `engines/blender.md`(部分验证:风格样片 `tabletop-miniature` 已用 Blender 5.2.2 渲染,项目用的命令还有几条没跑过;渲染时间先渲 3–5 帧校准) | HyperFrames + Three.js 层;重光影的镜头用 Blender | `showcase/04-intro-film/`、`cases/opus55-gallery.md` 的 3D 一节和第 6 节(Austerlitz 长片深读) | | 想要新点子、立意,一句话需求想做得出彩,或者不想千篇一律 | `playbook/12-ideation.md`,再加主类型文档 | 按主类型 | `cases/oneshot-five.md`、`cases/explainer-interstellar-blackhole.md` | | 想要某种风格、参考某部名作,或者不想每支片子都一个口味 | `styles/README.md`,再读选中预设的 `styles//STYLE.md` | 随主引擎 | 每个预设的 `media/swatch.mp4`,总览 `styles/gallery.jpg` | | 想知道某种镜头怎么动(开场、字卡、转场、卡点、收尾),或想要"专业的节奏" | `recipes/README.md`,再读 `recipes/sequences/` 里合适的骨架 | 随主引擎 | `cases/promo-video-shotcraft.md` | diff --git a/README.md b/README.md index 0a0d250..d6040a9 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ **Coding agents like Claude Code and Codex can make videos by writing programs. This makes them do it reliably.** -Explainers, science shorts, product films, music videos, data stories, paper talks, hand-drawn shorts, meme edits and edits of your own footage: 9 video types (09 experimental), 28 styles, one workflow. +Explainers, science shorts, product films, music videos, data stories, paper talks, hand-drawn shorts, meme edits and edits of your own footage: 9 video types (09 experimental), 29 styles, one workflow. **English** · [中文](README.zh-CN.md) · [Wiki](https://github.com/ZLHad/OpenVideoHarness/wiki) @@ -12,7 +12,7 @@ Explainers, science shorts, product films, music videos, data stories, paper tal ![Agents](https://img.shields.io/badge/agents-Claude%20Code%20%7C%20Codex-orange) ![Engines](https://img.shields.io/badge/engines-HyperFrames%20%7C%20Remotion%20%7C%20Manim%20%7C%20p5.brush-blue) ![Voice](https://img.shields.io/badge/voice-Qwen3--TTS%20zh%20%7C%20en-purple) -![Styles](https://img.shields.io/badge/styles-28-green) +![Styles](https://img.shields.io/badge/styles-29-green) OpenVideoHarness intro film @@ -32,7 +32,7 @@ OpenVideoHarness is that craft, written as docs and tools an agent can follow: - **A method for each kind of video.** Say "make a science short" or "make a launch film", and it reads the workflow for that type: which engine, which steps, what looks good, what is off limits. - **It stops and asks you three times.** At the outline, the storyboard and the first draft, it waits for your go-ahead. Direction gets settled while changes are still cheap. For a quick try, switch to the `quick` level and it just renders. -- **More than one taste.** 28 styles learned from famous work, each with a real rendered sample, offered to you before anything is built. +- **More than one taste.** 29 styles learned from famous work, each with a real rendered sample, offered to you before anything is built. - **It checks its own work.** An agent can't watch video or hear sound, so it looks at rendered frames, measures the mix, and fixes things until a checklist passes. A reviewer who didn't make the film then scores it. - **Sound included.** Chinese and English voiceover (a local open-source model), bilingual subtitles, music and sound effects written as code, mixing and a final audio check. @@ -95,8 +95,8 @@ The five films below were made by an agent **reading only this repo's docs**. Cl 04 · Intro film (one-take 3D) (HyperFrames + Three.js · 81 s · 1920×1080)
The repo's own product film, one continuous 3D take.
Request, as revised at gate ①: “一镜到底 动画动效 音乐动态字等风格 叙事感 科幻感大片感” (one continuous shot, kinetic type on music, a narrative arc, a sci-fi blockbuster feel)
Suggested workflow (studio effort, --effort studio):
bin/vh new promo intro-film --style monumental-scifi
one-take 3D: playbook/08; bin/vh sfx place, sheet, check
Sound: a code-composed cinematic score (D minor, 90 BPM) and 97 sound effects; zh/en soft subtitle tracks -The 28 style samples, all showing the same content
▶ the reel, with sound (42 s) -28 styles, one reel (5-second samples)
The same content in 28 styles learned from famous work.
Start from one:
bin/vh new promo launch-film --style cutout-jazz
bin/vh style list shows all 28; details in styles/README.md
Sound: one score per sample (bin/vh music, mix … profile=swatch) +The 29 style samples, all showing the same content
▶ the reel, with sound (42 s) +29 styles, one reel (5-second samples)
The same content in 29 styles learned from famous work.
Start from one:
bin/vh new promo launch-film --style cutout-jazz
bin/vh style list shows all 29; details in styles/README.md
Sound: one score per sample (bin/vh music, mix … profile=swatch) @@ -121,26 +121,26 @@ The GIFs are compressed, silent previews. Films you make with it are welcome in -## 28 styles, not one taste +## 29 styles, not one taste AI-made videos drift toward one look: dark background, glow, glass cards, busy animated UI. Unless you say otherwise, that's where an agent goes. -So we studied famous work and wrote down 28 styles in [`styles/`](styles/), grouped into film titles, brand and launch, data and explainers, illustration and print, Chinese aesthetics, and retro tech. The sources include: -- **film and title design**: Saul Bass's titles, *Se7en*, *Blade Runner 2049*, Wes Anderson's symmetry, Wong Kar-wai's step-printing; +So we studied famous work and wrote down 29 styles in [`styles/`](styles/), grouped into film titles, brand and launch, data and explainers, illustration and print, Chinese aesthetics, and retro tech. The sources include: +- **film and title design**: Saul Bass's titles, *Se7en*, *Blade Runner 2049*, Wes Anderson's symmetry, Wong Kar-wai's step-printing, Aardman's and Laika's stop-motion miniatures; - **design**: the Swiss grid, 3Blue1Brown, New York Times data graphics, Otto Neurath's Isotype pictograms; - **animation and print**: the halftone dots of *Spider-Verse*, 16-bit Super Nintendo pixel art; - **Chinese aesthetics**: ink wash (水墨), Dunhuang murals, shadow puppetry and guochao. Each style is written as instructions an agent can follow: colors and fonts, composition, how things move, how scenes change, what it sounds like, and which clichés to avoid. -**Every style comes with a real 5-second sample rendered by this repo**, each with its own code-written music. All 28 samples show exactly the same content, so the only difference is the style: +**Every style comes with a real 5-second sample rendered by this repo**, each with its own code-written music. All 29 samples show exactly the same content, so the only difference is the style: -The 28 style samples, all showing the same content +The 29 style samples, all showing the same content Watch them back to back, each with its own sound, in [`styles/gallery.mp4`](styles/gallery.mp4). To use one: ```bash -bin/vh style list # see all 28 +bin/vh style list # see all 29 bin/vh new promo launch-film --style cutout-jazz # start a project from a style ``` @@ -342,7 +342,7 @@ OpenVideoHarness/ ├── video-types/ workflows for the 9 video types (09 experimental) ├── playbook/ shared know-how 00–12: pipeline, checks, motion, sound, effects, narrative, hooks and covers, composition, concept ├── templates/ files each new project fills in: brief, storyboard, style, review, decisions, notes, lessons, checklist; script, character and packaging when needed -├── styles/ 28 styles, each with a sample; _swatch/ renders the samples +├── styles/ 29 styles, each with a sample; _swatch/ renders the samples ├── recipes/ shot recipes: how a shot moves (frames, critical values, pitfalls) + pacing skeletons for whole films ├── cases/ 13 case studies + curated community work + a 3D long-form deep-dive ├── showcase/ films made with this repo (source + final + process notes) @@ -402,7 +402,7 @@ This is an independent project, not affiliated with Anthropic, HeyGen, Remotion, ## License -Original content is [MIT](LICENSE). The bundled ClaudeAnimationBase is also MIT (© John Heibel). Some files in `recipes/` are modified from Apache-2.0 projects (video-shotcraft, HyperFrames): their upstream parts stay under Apache-2.0, and [`recipes/NOTICE.md`](recipes/NOTICE.md) lists them. Reference repos keep their own licenses. +Original content is [MIT](LICENSE). The bundled ClaudeAnimationBase is also MIT (© John Heibel). Some files in `recipes/` are modified from Apache-2.0 projects (video-shotcraft, HyperFrames): their upstream parts stay under Apache-2.0, and [`recipes/NOTICE.md`](recipes/NOTICE.md) lists them. Files that call Blender's Python API (`import bpy`: `styles/_swatch/blender_render.py` and the Blender style scenes such as `styles/tabletop-miniature/swatch.py`) are GPL-3.0-or-later, as Blender asks of published bpy scripts; each carries an SPDX header (see [`engines/blender.md`](engines/blender.md), "许可证"). Reference repos keep their own licenses. ## Citation diff --git a/README.zh-CN.md b/README.zh-CN.md index 8b0e0af..ed1b4ad 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -4,7 +4,7 @@ **让 Claude Code、Codex 这类写代码的 AI,用写程序的方式做视频,而且做得稳。** -科普、讲解、产品片、MV、数据、论文、手绘、梗图快剪、真人素材剪辑:9 类视频(09 实验中),28 种风格,一套流程。 +科普、讲解、产品片、MV、数据、论文、手绘、梗图快剪、真人素材剪辑:9 类视频(09 实验中),29 种风格,一套流程。 [English](README.md) · **中文** · [Wiki](https://github.com/ZLHad/OpenVideoHarness/wiki) @@ -12,7 +12,7 @@ ![Agents](https://img.shields.io/badge/agents-Claude%20Code%20%7C%20Codex-orange) ![Engines](https://img.shields.io/badge/engines-HyperFrames%20%7C%20Remotion%20%7C%20Manim%20%7C%20p5.brush-blue) ![Voice](https://img.shields.io/badge/voice-Qwen3--TTS%20zh%20%7C%20en-purple) -![Styles](https://img.shields.io/badge/styles-28-green) +![Styles](https://img.shields.io/badge/styles-29-green) OpenVideoHarness 介绍片 @@ -32,7 +32,7 @@ OpenVideoHarness 就是这套行规,写成了 AI 能照着执行的文档和 - **按片子类型给做法**:你说"做个科普"或"做个发布片",它就去读那一类的工作流:用哪个引擎、分几步、什么算好看、什么不许做。 - **三个节点停下来问你**:大纲、分镜、初版,每到一处都等你点头再往下做。方向在最便宜的时候定下来。只想快速试一版时,可以切到"快出"档,直接出片。 -- **不止一种口味**:28 个从名作里学来的风格,每个都附一段真渲的样片,开工前让你挑。 +- **不止一种口味**:29 个从名作里学来的风格,每个都附一段真渲的样片,开工前让你挑。 - **自己检查自己**:AI 看不了视频,也听不了声音。所以让它看渲染出来的帧、测混音的数据,照着清单改到合格;整片还要交给一个没参与制作的 reviewer 打分。 - **声音一起管**:中英配音(本地开源模型)、双语字幕、用代码写配乐和音效、混音和质检。 @@ -95,8 +95,8 @@ cd ~/OpenVideoHarness && claude 04 · 介绍片(一镜到底 3D)(HyperFrames + Three.js · 81 秒 · 1920×1080)
本仓库自己的产品片,一个连续的 3D 长镜头。
提示词(关卡 ① 时改的方向):“一镜到底 动画动效 音乐动态字等风格 叙事感 科幻感大片感”
建议工作流(精品档,--effort studio):
bin/vh new promo intro-film --style monumental-scifi
一镜到底 3D 见 playbook/08;bin/vh sfx place、sheet、check
声音:代码写的电影感配乐(D 小调,90 BPM)和 97 个音效;中英软字幕轨 -28 种风格的样片,内容完全相同
▶ 带声音的连播(42 秒) -28 种风格,连播(每段 5 秒)
同一段内容,换 28 种从名作里学来的风格。
从一种开始:
bin/vh new promo launch-film --style cutout-jazz
bin/vh style list 列出全部 28 种,详见 styles/README.md
声音:每段样片一首配乐(bin/vh music,mix … profile=swatch) +29 种风格的样片,内容完全相同
▶ 带声音的连播(42 秒) +29 种风格,连播(每段 5 秒)
同一段内容,换 29 种从名作里学来的风格。
从一种开始:
bin/vh new promo launch-film --style cutout-jazz
bin/vh style list 列出全部 29 种,详见 styles/README.md
声音:每段样片一首配乐(bin/vh music,mix … profile=swatch) @@ -121,26 +121,26 @@ GIF 是压缩过的无声预览。你做出来的片子也欢迎 PR 进 `showcas -## 28 种风格,不止一种口味 +## 29 种风格,不止一种口味 AI 做的视频很容易长成一个样子:暗底、发光、玻璃卡片、满屏动态 UI。你不说,它就往这个方向走。 -所以我们从名作里学了 28 种风格,放在 [`styles/`](styles/),分成六类:电影片头、品牌发布、数据讲解、插画印刷、中国美学、复古科技。学习对象包括: -- **电影和片头**:Saul Bass 的片头、《七宗罪》、《银翼杀手 2049》、韦斯·安德森的对称构图、王家卫的抽帧; +所以我们从名作里学了 29 种风格,放在 [`styles/`](styles/),分成六类:电影片头、品牌发布、数据讲解、插画印刷、中国美学、复古科技。学习对象包括: +- **电影和片头**:Saul Bass 的片头、《七宗罪》、《银翼杀手 2049》、韦斯·安德森的对称构图、王家卫的抽帧、Aardman 和 Laika 的定格微缩; - **设计**:瑞士网格、3Blue1Brown、《纽约时报》的数据图、纽拉特的图形统计(Isotype); - **动画和印刷**:《蜘蛛侠:平行宇宙》的网点、超级任天堂的 16 位像素; - **中国美学**:水墨、敦煌、皮影、国潮。 每种风格都写成一份 AI 能照着做的说明:用什么颜色和字体、怎么构图、东西怎么动、怎么转场、配什么声音、哪些俗套不许碰。 -**每种风格都用本仓库真渲了一段 5 秒样片**,配乐也是各自用代码写的。28 段样片的内容一模一样,差别只在风格: +**每种风格都用本仓库真渲了一段 5 秒样片**,配乐也是各自用代码写的。29 段样片的内容一模一样,差别只在风格: -28 种风格的样片,内容完全相同 +29 种风格的样片,内容完全相同 连着看的版本在 [`styles/gallery.mp4`](styles/gallery.mp4),每段带着自己的声音。用法: ```bash -bin/vh style list # 看 28 种风格 +bin/vh style list # 看 29 种风格 bin/vh new promo launch-film --style cutout-jazz # 建项目时直接带上一种风格 ``` @@ -390,7 +390,7 @@ OpenVideoHarness/ ├── video-types/ 9 类视频的工作流(09 实验中) ├── playbook/ 通用知识 00–12:流程、自查、运动设计、声音、特效、叙事、钩子与封面、作曲、立意等 ├── templates/ 每个新项目要填的文件:需求、分镜、风格、审阅、决定、笔记、经验、清单;按需再加旁白稿、角色、标题封面 -├── styles/ 28 种风格,各带样片;_swatch/ 是样片渲染器 +├── styles/ 29 种风格,各带样片;_swatch/ 是样片渲染器 ├── recipes/ 镜头配方:一镜怎么动(帧数、命门、坑)+ 整支片子的节奏骨架 ├── cases/ 13 个案例拆解 + 社区作品精选 + 一支 3D 长片深读 ├── showcase/ 本仓库自己做的片子(源码 + 成片 + 过程记录) @@ -450,7 +450,7 @@ OpenVideoHarness/ ## 许可 -原创内容采用 [MIT](LICENSE) 许可。自带的 ClaudeAnimationBase 也是 MIT(© John Heibel)。`recipes/` 里有些文件改编自 Apache-2.0 的项目(video-shotcraft、HyperFrames),来自上游的部分仍按 Apache-2.0,清单见 [`recipes/NOTICE.md`](recipes/NOTICE.md)。参考仓库遵循各自的许可证。 +原创内容采用 [MIT](LICENSE) 许可。自带的 ClaudeAnimationBase 也是 MIT(© John Heibel)。`recipes/` 里有些文件改编自 Apache-2.0 的项目(video-shotcraft、HyperFrames),来自上游的部分仍按 Apache-2.0,清单见 [`recipes/NOTICE.md`](recipes/NOTICE.md)。调用 Blender Python API 的文件(`import bpy`:`styles/_swatch/blender_render.py` 和 `styles/tabletop-miniature/swatch.py` 这类 Blender 风格场景)按 GPL-3.0-or-later 分发,这是 Blender 对公开发布的 bpy 脚本的要求;每个文件头都有 SPDX 标注(见 [`engines/blender.md`](engines/blender.md) 的"许可证")。参考仓库遵循各自的许可证。 ## 引用 diff --git a/bin/vh b/bin/vh index 98db557..af402f9 100755 --- a/bin/vh +++ b/bin/vh @@ -364,7 +364,10 @@ cmd_cover_preview() { [ $# -gt 0 ] || { echo "usage: bin/vh cover-preview /{STYLE.md,tokens.json,swatch.js,media/}; renderer in styles/_swatch @@ -381,7 +384,7 @@ for d in sorted(pathlib.Path(sys.argv[1]).iterdir()): PY ;; gallery) shift; uv run -q --no-project --with pillow python "$sw/gallery.py" "$@" ;; - check) shift; swatch_deps; "$sw/determinism.sh" "$@" ;; + check) shift; swatch_deps "${1:-}"; "$sw/determinism.sh" "$@" ;; compare) shift; [ $# -gt 0 ] || { echo "usage: bin/vh style compare a,b,c [--frame t] [--out file.png]"; exit 1; } uv run -q --no-project --with pillow python "$ROOT/tools/style_compare.py" "$@" ;; apply) shift; [ $# -eq 2 ] || { echo "usage: bin/vh style apply (bin/vh style list shows the presets)"; exit 1; } @@ -390,7 +393,7 @@ PY [ -f "$dir/BRIEF.md" ] && [ -f "$dir/STYLE.md" ] || { echo "$(rel "$dir") has no BRIEF.md and STYLE.md: not a bin/vh project"; exit 1; } attach_style "$dir" "$1" echo "$c_ok styles/$1 attached to $(rel "$dir") (STYLE_PRESET.md, style.tokens.json, its prompt block in BRIEF.md)" ;; - *) swatch_deps; exec "$sw/render.sh" "$@" ;; + *) swatch_deps "$1"; exec "$sw/render.sh" "$@" ;; esac } diff --git a/docs/assets/overview.en.svg b/docs/assets/overview.en.svg index 427f3f1..9d6a697 100644 --- a/docs/assets/overview.en.svg +++ b/docs/assets/overview.en.svg @@ -34,7 +34,7 @@ rect{stroke-width:0.8} Final: reproducible, editable -Knowledge9 video types · 13 playbook docs28 styles, each with a sample13 case studies30 reference repos +Knowledge9 video types · 13 playbook docs29 styles, each with a sample13 case studies30 reference repos Tools and enginesbin/vh, 20+ commandsHyperFrames · Manimp5.brush hand-drawn enginescore · voice · mix · QA diff --git a/docs/assets/overview.zh.svg b/docs/assets/overview.zh.svg index 6087b10..fabfd3b 100644 --- a/docs/assets/overview.zh.svg +++ b/docs/assets/overview.zh.svg @@ -34,7 +34,7 @@ rect{stroke-width:0.8} 成片:可复现、可修改 -知识库9 类视频 · 13 篇 playbook28 种风格,都有样片13 个案例拆解30 个参考仓库 +知识库9 类视频 · 13 篇 playbook29 种风格,都有样片13 个案例拆解30 个参考仓库 工具与引擎bin/vh 二十多个命令HyperFrames · Manimp5.brush 手绘引擎作曲 · 配音 · 混音 · QA diff --git a/engines/README.md b/engines/README.md index ee662bc..f24fdd2 100644 --- a/engines/README.md +++ b/engines/README.md @@ -134,12 +134,13 @@ uv run manim -qh --fps 30 scene.py MyScene # 成片:1080p30(-qh 默认 - 写代码前先读 `references/repos/3brown1blue/src/three_b1b/skill/SKILL.md` 里的 Gotchas。 - 注意 CE 和 ManimGL 的 API 不能混用,参考 `references/repos/3brown1blue/src/three_b1b/skill/rules/manimgl-differences.md`。 -## Blender,未安装,按需使用(实验性) +## Blender,按需使用(部分验证) -完整指南:[`blender.md`](blender.md)。**实验性:维护者的 Mac 没有装 Blender,指南没有验证过;渲染时间先渲 5 帧校准。** +完整指南:[`blender.md`](blender.md)。**部分验证:维护者的 Mac 装了 Blender 5.2.2,风格样片 `tabletop-miniature` 用它渲染(`styles/_swatch/README.md` 的"Blender 场景");指南里项目用的两段式命令有几条还没跑过。渲染时间先渲 3–5 帧校准。** - 安装:`brew install --cask blender`,也可以从官网下载。指南钉在 5.2 LTS(5.0 起只支持 Apple Silicon,Python API 有破坏性改动)。 - 渲染用脚本方式,保证结果可复现,分两段:`blender -b --factory-startup --python build.py -- …` 生成 `scene.blend`,再 `blender -b scene.blend … -a` 渲 PNG 序列。同时固定随机种子,并烘焙好模拟缓存。 +- 能跑的样板:`styles/_swatch/blender_render.py`(逐帧 `apply(t)` 再渲,正式版走 CPU 求逐像素相同)、`blender_prep.py`(渲染前的静态检查和字体解析)和 `render.sh` 里的 `bl_run`(`env -i` 加 `sandbox-exec`)。调用 bpy 的文件按 GPL-3.0-or-later 分发(见指南的"许可证")。 - 官方的 MCP server 和社区的 `ahujasid/mcp-for-blender` 都会直接执行 LLM 生成的 Python,没有任何防护。**默认不用**:要用先问用户,放在虚拟机或单独的 macOS 用户下;没有沙箱,就不要让 LLM 生成的 bpy 代码经过它们执行。管线里跑 agent 写的脚本,加静态检查、`sandbox-exec` 和 `env -i`(见指南的"安全"一节)。 ## 生成式视频(fal 等),按需使用 diff --git a/engines/blender.md b/engines/blender.md index c289576..8a5cc13 100644 --- a/engines/blender.md +++ b/engines/blender.md @@ -1,8 +1,8 @@ # Blender 引擎指南(实验性) -> **实验性(experimental, not yet verified on this machine):维护者的 Mac(M3 Max)没有装 Blender**,下面所有 Blender 命令、API 和数字都来自官方文档、release notes 和 issue,没有跑过。ffmpeg、色彩、alpha、EXR 和 `sandbox-exec` 相关的结论在维护者的 Mac 上跑过,标【实测】。**渲染时间先渲 5 帧校准,把结果写进 BRIEF**(见"渲染时间")。 +> **部分验证(partly verified)**:2026-10-01 维护者的 Mac(M3 Max,macOS 15)装上了 Blender 5.2.2 LTS,风格库的 `tabletop-miniature` 样片(`styles/_swatch/` 的 Blender 场景)是在它上面做的。"首次冒烟"里做过的几项已经写回本文,标【实测 5.2.2】;没做的几项和其余的 Blender 命令、API 和数字仍来自官方文档、release notes 和 issue。ffmpeg、色彩、alpha、EXR 和 `sandbox-exec` 相关的结论标【实测】。**渲染时间先渲 3–5 帧校准,把结果写进 BRIEF**(见"渲染时间")。 > -> 标记:【实测】在维护者的 Mac(macOS 15,ffmpeg 8.0.1)上跑过;【二手】只读到搜索摘要或第三方转述,没能打开原文;【推测】没有证据的推断。引用编号 `[n]` 见文末"来源"。`bin/vh` 里还没有 Blender 的子命令,下文都是直接调用 `blender`。首次装上 Blender 之后,先做"首次冒烟"里的几项,把结果写回本文,再去掉这段警告。 +> 标记:【实测】在维护者的 Mac(macOS 15,ffmpeg 8.0.1)上跑过;【实测 5.2.2】用 Blender 5.2.2 跑过;【二手】只读到搜索摘要或第三方转述,没能打开原文;【推测】没有证据的推断。引用编号 `[n]` 见文末"来源"。`bin/vh` 里没有项目用的 Blender 子命令,下文都是直接调用 `blender`;风格样片走 `bin/vh style `,做法见 `styles/_swatch/README.md` 的"Blender 场景",那里的 `blender_render.py` 是一个能跑的逐帧渲染器。 ## 要点 @@ -13,7 +13,7 @@ 5. **纯函数**:时间线用我们自己的缓动、样条和节拍函数,逐帧采样成关键帧;不用 Python handler,不靠实时模拟。 6. **合成与颜色**:默认交 PNG(straight alpha,视图变换已烘进去);EXR 是 scene-linear,进 ffmpeg 要显式 `-apply_trc iec61966_2_1`;最后一步 H.264 要写 BT.709 矩阵和四个标签,否则饱和色偏 20 个色阶左右。 7. **安全**:官方 MCP 自己警告,它会直接执行 LLM 生成的代码,没有任何防护 [16]。**没有沙箱,就不要让 LLM 生成的 bpy 代码经过任何 MCP 执行**;管线里跑 agent 写的脚本同理。 -8. **许可**:输出归自己,但公开发布的、调用 bpy 的脚本要以 GPL 兼容协议发布 [17]。仓库是 MIT,这里的做法**维护者待定**(见"许可证")。 +8. **许可**:输出归自己,但公开发布的、调用 bpy 的脚本要以 GPL 兼容协议发布 [17]。本仓库的做法(维护者 2026-10-01 决定):import bpy 的文件标 `SPDX-License-Identifier: GPL-3.0-or-later`,按 GPL 分发,其余仍是 MIT(见"许可证")。 ## 什么时候用 Blender @@ -215,7 +215,7 @@ ffprobe -v error -select_streams v:0 -show_entries stream=pix_fmt,color_range,co **管线里跑 agent 写的 `build.py`**:① 静态检查:AST 扫描,禁 `os`、`subprocess`、`socket`、`urllib`、`shutil`、`eval/exec`、`__import__`,`open` 只许写输出目录;② `--factory-startup`、不加 `-y`;③ 套 `sandbox-exec` 和 `env -i`(下)。第三方 `.blend` 和素材当不可信输入:先 `--disable-autoexec`(默认已是)打开,扫描文本块和驱动器再用。要联网取素材,单独做一步,显式 URL、记来源和许可,不在渲染进程里取。 -**`sandbox-exec`**(手册标注 DEPRECATED,但在 macOS 15 上可用)。下面的 profile 在 `sh`、`curl`、`python3`、`ffmpeg` 上验证过:输出目录可写;其他位置(包括 `/tmp` 和真实的 home)写入得到 `Operation not permitted`;网络被拒(`curl` 返回 000,不加沙箱时是 200)【实测】。**没有用 Blender 本体验证过。** +**`sandbox-exec`**(手册标注 DEPRECATED,但在 macOS 15 上可用)。下面的 profile 在 `sh`、`curl`、`python3`、`ffmpeg` 上验证过:输出目录可写;其他位置(包括 `/tmp` 和真实的 home)写入得到 `Operation not permitted`;网络被拒(`curl` 返回 000,不加沙箱时是 200)【实测】。套 Blender 本体还要补几行,见下面的"首次冒烟"和 `styles/_swatch/render.sh` 的 `bl_profile`(一份在 Blender 5.2.2 上跑通的完整 profile)。 ```scheme (version 1) @@ -234,9 +234,9 @@ sandbox-exec -f vh_blender.sb env -i PATH="$PATH" HOME="$PWD/blender/out/.home" blender -b --factory-startup ... ``` -Blender 自己需要写的位置(着色器缓存、用户配置目录)和 `env -i` 下还缺的环境变量都还没验证【未实测】,首次冒烟时按报错补白名单。沙箱不是安全边界的终点:`(allow default)` 只挡了网络和写入,读取 `~/.ssh`、`~/.zsh_secrets` 这类文件仍然放行(验证过)。要更严,在 profile 的 `(allow default)` 之后加一行拒读,例如 `(deny file-read* (subpath "/Users//.ssh") (literal "/Users//.zsh_secrets"))`(路径写绝对路径;实测读被拒,python 照常运行)。 +沙箱不是安全边界的终点:`(allow default)` 只挡了网络和写入,读取 `~/.ssh`、`~/.zsh_secrets` 这类文件仍然放行(验证过)。要更严,在 profile 的 `(allow default)` 之后加一行拒读,例如 `(deny file-read* (subpath "/Users//.ssh") (literal "/Users//.zsh_secrets"))`(路径写绝对路径;实测读被拒,python 照常运行);或者整个家目录拒读,再放行项目和字体目录(样片的正式渲染就是这样)。用 Metal 渲染时整个家目录拒读会崩,见"首次冒烟"。 -## 许可证(维护者待定) +## 许可证(2026-10-01 已定:选项 (2)) 以下是官方原文的要点,不是法律意见;许可页和 FAQ 的原文 2026-10-01 对着页面核对过 [17]。 @@ -249,7 +249,7 @@ Blender 自己需要写的位置(着色器缓存、用户配置目录)和 `e | 官方 MCP、`bpy` PyPI 包 | 元数据都标 GPL-3.0 [16][18] | 只读参考 | | 素材 | 各自许可:Poly Haven 等为 CC0,Poly Pizza 多为 CC-BY,Sketchfab 逐件不同 [16] | 一律记素材台账 | -**维护者待定**:本仓库是 MIT。`engines/blender/` 下如果放调用 bpy 的脚本,许可怎么写,有三个选项:(1) 仓库里不放 `import bpy` 的文件,`build.py` 由 agent 在项目目录里生成(`projects/` 不入库),仓库只放不 import bpy 的封装和模板 JSON;(2) `import bpy` 的文件标 `SPDX-License-Identifier: GPL-3.0-or-later`,在 `ACKNOWLEDGMENTS.md` 里说明,这部分文件按 GPL 分发;(3) 保持 MIT,承担 FAQ 字面要求和 MIT 之间的差距。**决定之前按 (1) 做**:仓库里不放 `import bpy` 的文件,本指南也只有流程、伪代码和 API 名称。Blender 的名称和 logo 受单独的商标政策约束,片子里出现 Blender 界面截图前先看一眼 [17]。 +本仓库是 MIT。调用 bpy 的脚本放进仓库时,许可怎么写,原有三个选项:(1) 仓库里不放 `import bpy` 的文件,`build.py` 由 agent 在项目目录里生成(`projects/` 不入库),仓库只放不 import bpy 的封装和模板 JSON;(2) `import bpy` 的文件标 `SPDX-License-Identifier: GPL-3.0-or-later`,这部分文件按 GPL 分发;(3) 保持 MIT,承担 FAQ 字面要求和 MIT 之间的差距。**维护者 2026-10-01 选了 (2)**:现在仓库里 import bpy 的文件是 `styles/_swatch/blender_render.py` 和 `styles/tabletop-miniature/swatch.py`,文件头都有 SPDX 标注,`README.md` 的 License 一节写明了;不 import bpy 的封装(`blender_prep.py`、`render.sh`)仍是 MIT。以后加 import bpy 的文件,照样标。项目里 agent 生成的 `build.py` 在 `projects/` 下,不入库,不受影响。Blender 的名称和 logo 受单独的商标政策约束,片子里出现 Blender 界面截图前先看一眼 [17]。 ## 流程与验证 @@ -277,14 +277,30 @@ Blender 自己需要写的位置(着色器缓存、用户配置目录)和 `e ## 首次冒烟(装上 Blender 之后) +2026-10-01 用 5.2.2(Homebrew cask,M3 Max)做过的【实测 5.2.2】: + +- **同一帧、同一设置、新进程渲两次**(一个简单场景:木纹桌面、一个方块、一行中文、两盏灯,1920×1080,64 spp + OIDN):CPU 上的 Cycles 逐像素相同;Metal 上的 Cycles 不同,PSNR 92 dB;EEVEE 不同,85 dB。都在 45 dB 线以上,但只有 CPU 能做到逐像素相同。风格样片的正式版因此走 CPU;草稿走 Metal。 +- **乱序、多进程**:`tabletop-miniature` 的 12 帧倒序分给 3 个新进程重渲,和整片按顺序渲出来的同一帧比(`styles/_swatch/determinism.sh`),结果见 `styles/_swatch/README.md`。 +- **速度**:上面那个简单场景每帧 CPU 21 s、Metal 4.5 s、EEVEE 1.1 s(含启动)。`tabletop-miniature`(约 70 个物体、文字、景深、4 盏灯)CPU 64 spp 每帧 32–43 s,32 spp 每帧 15–19 s,两者并排放大看不出差别;Metal 20 spp 每帧约 1.6 s。 +- **`sandbox-exec` 套 Blender**(完整的 profile 见 `styles/_swatch/render.sh` 的 `bl_profile`): + - 只放行输出目录时,Metal 不能写着色器缓存,每帧都重编(2 s 变成 13 s)。再放行本用户缓存目录里 Blender 自己的子目录(`$(getconf DARWIN_USER_CACHE_DIR)org.blenderfoundation.blender`)就正常了;临时目录不用放行。日志里仍有几行无害的 "Error creating directory"。 + - 冷启动时 Metal 编译内核要静默约 110 s,日志一行不动:看门狗的静默阈值要放宽(样片用 300 s)。 + - 整个家目录拒读(只放行项目、Blender 安装目录和 `~/Library/Fonts`):CPU 渲染照常,和不加这条时逐像素相同。Metal 在内核已经缓存好时会崩溃(SIGSEGV,崩在 `-[_MTLDevice recordBinaryArchiveUsage:]`),放行 `~/Library` 也不行。所以样片只在正式渲染(CPU)上加这条,草稿(Metal)仍然断网、只写输出目录,但不禁读。 + - `env -i` 只带 `PATH`、`LANG`,`HOME` 和 `TMPDIR` 指进输出目录,Blender 照常运行,Cycles 的内核缓存写到 `$HOME/.cache/cycles`。 +- **字体**:`bpy.data.fonts.load()` 只读 .ttc 的第一个字形:`Songti.ttc` 读出 Songti SC Black,`Hiragino Sans GB.ttc` 读出 W3。要别的字重,先把那一面写成单独的字体文件(`styles/_swatch/blender_prep.py` 用 fontTools 做)。 +- **API**:5.2 里新建的材质和世界自带节点树,再设 `use_nodes` 会报 DeprecationWarning(6.0 删除);Mix 节点有三组同名输入(float、vector、color 都叫 "A"),要按 identifier 取(`A_Color`、`Factor_Float`、`Result_Color`);`view_transform` 和 `look` 是动态枚举,`bl_rna` 里查不到选项,直接设、失败再退(`AgX` 和 `AgX - Medium High Contrast` 都可用);后台模式下 `stdout` 是块缓冲,Cycles 的进度行不会实时进日志,渲染器要自己 `print(..., flush=True)`,否则看门狗会以为卡住了。 +- **persistent data 会留下跨帧状态**:一个进程里按顺序逐帧 `apply(t)` 再 `bpy.ops.render.render()`,开着 `render.use_persistent_data` 时,CPU 上的 Cycles 在一段帧里把一个物体(茶杯)渲成全黑,单独渲同一帧是正常的;乱序重渲 12 帧,有 1 帧对不上(24.5 dB)。关掉以后每帧时间几乎不变。逐帧改属性再渲的流程不要开它,开了就要做乱序比对。 +- **job control**:在 `set -m` 打开的 shell 里把 Blender 放到后台,它会进另一个进程组,看门狗按组杀不到它;在起 Blender 的子 shell 里先 `set +m`。 + +还没做的: + 1. 5.2 上 EEVEE 命令行渲 300 帧,看内存曲线(#125333 的后续)。 -2. Cycles Metal 的确定性:`-f N` 对 `-a`、单进程对多进程、重启前后;自适应采样开、关各一组。 +2. Cycles Metal 的确定性:`-f N` 对 `-a`、单进程对多进程、重启前后;自适应采样开、关各一组(CPU 的乱序一致见上)。 3. OIDN 开、关的静态区域闪烁。 4. 刚体烘焙缓存乱序渲染是否一致。 -5. `sandbox-exec` 套 Blender 本体:着色器缓存和用户配置目录要补哪些写目录。 -6. HyperFrames 的 `