Repository navigation
docs(skills): teach shared cut constants and fill lights for Three.js scenes - #5077
Merged
Merged
Conversation
… scenes The three adapter skill had no guidance for camera cuts made inside one canvas. A visibility window written as its own literal near a cut shows the next shot's objects for the last frames of the previous shot, a two-frame pop-in that a still per shot does not reveal. The skill now says to declare each cut once, read it in both the shot selector and every visibility window, and snapshot the last frame before each cut. It also explains why a MeshStandardMaterial lit by a single key light renders as a flat black cutout when the camera faces that light, and to add a fill such as a HemisphereLight driven at a fixed ratio to the key. Signed: Miga Co-Authored-By: Miguel Ángel <miguel.sierra@heygen.com>
terencecho
approved these changes
Oct 5, 2026
terencecho
left a comment
Contributor
There was a problem hiding this comment.
No blocker at b6999bc4fdf97ba42f693092eff36efa1eaafe63. Approving; the CI jobs were all green when I stamped (26 pass, 30 skipping).
What I checked
- Effective diff is
skills/hyperframes-animation/adapters/three.md(+32/-1 across two sections) and theskills-manifest.jsonhash line; nothing else. bun packages/cli/scripts/gen-skills-manifest.ts --checkon the PR head: "skills-manifest.json is in sync (21 skills)".- The CLI claims hold:
snapshothas--atand--no-end(packages/cli/src/commands/snapshot.ts, the--no-endtext says it captures only your exact--attimes).(Math.ceil(23*30)-1)/30 = 689/30 = 22.9667. - The pop-in claim: against a cut at 23, a window of
t > 22.9is true for frames 688 (22.9333) and 689 (22.9667) and false for frame 687 (22.9), so it is a two-frame leak at 30 fps, as written. - The sample is self-consistent:
CUT_B/CUT_Care read by bothshotForand the visibility window, andrenderAt(t)is the existing adapter shape used above it in the file. - The lighting advice is standard Three.js behaviour: a
MeshStandardMaterialwith only a point or directional light and no ambient, env map or emissive is black on its unlit side. AHemisphereLightfill with its own intensity (the units differ from the key light) is sound. - No credentials or URLs beyond the existing CLI usage.
Non-blocking
- The Camera Cuts sample is a pattern, not a runnable file (
shotA/shotB/shotCand the prop arrays are placeholders); it reads as intended in context.
Reviewed on b6999bc4fdf97ba42f693092eff36efa1eaafe63. This is a review verdict, not authorization to merge.
— Review by tai (pr-review)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
skills/hyperframes-animation/adapters/three.mdgains two sections:snapshot --at (ceil(cut*fps)-1)/fps.MeshStandardMateriallit by a single key light, with no ambient, env map or emissive, renders as a flat black cutout when the camera faces the light. Add a fill such as aHemisphereLightdriven from the same source as the key at a fixed ratio, not the same number.skills-manifest.jsonis regenerated.Why
A Three.js composition that switched shots by time had visibility windows written as separate literals (
t > 22.9against a cut att < 23). At 30 fps that put the next shot's meshes into frames 688 and 689 of the previous shot. Checking one still per shot did not catch it. The same scene's rocks, lit only by a sunPointLightwhile the camera faced the sun, rendered as black silhouettes. The skill covered neither case.A re-render with the CLI matched the original output frame for frame (PSNR 34 to 39 dB), so neither problem comes from the engine.
Verification
bun packages/cli/scripts/gen-skills-manifest.ts --check: in sync (21 skills).oxfmt --check: clean.snapshot --atseeks the exact instant (snapshot.ts,exactTime: true), and(ceil(23*30)-1)/30 = 22.9667is frame 689.tat top level and that it implied copying the key light's intensity onto the fill. Both are fixed in this head.Signed: Miga