diff --git a/skills-manifest.json b/skills-manifest.json index 56b6257f30..0e3d9354ef 100644 --- a/skills-manifest.json +++ b/skills-manifest.json @@ -22,7 +22,7 @@ "files": 29 }, "hyperframes-animation": { - "hash": "5a771a306ac3b34e", + "hash": "6af72990949385ca", "files": 122 }, "hyperframes-audio": { diff --git a/skills/hyperframes-animation/adapters/three.md b/skills/hyperframes-animation/adapters/three.md index 4c532b46b5..0f18e42651 100644 --- a/skills/hyperframes-animation/adapters/three.md +++ b/skills/hyperframes-animation/adapters/three.md @@ -114,6 +114,37 @@ function renderAt(time) { If several mixers exist, seek all of them from the same `time`. +## Camera Cuts Inside One Canvas + +When one scene switches camera shots by time, declare each cut once and read that constant everywhere: in the camera's shot selector and in every object's visibility window. A window written as its own literal near the cut (`t > 22.9` against a cut at `t < 23`) shows the next shot's objects in the last frames of the previous shot. At 30 fps that is a two-frame pop-in, which one still per shot will not show. + +```js +const CUT_B = 23; +const CUT_C = 35; + +function shotFor(t) { + if (t < CUT_B) return shotA(t); + if (t < CUT_C) return shotB(t); + return shotC(t); +} + +function renderAt(t) { + const shot = shotFor(t); + camera.position.copy(shot.position); + camera.lookAt(shot.target); + shotBProps.forEach((mesh) => { + mesh.visible = t >= CUT_B && t < CUT_C; + }); + renderer.render(scene, camera); +} +``` + +Verify each cut on the last frame before it and the first frame after it, not only somewhere inside each shot. The last frame before a cut is `(Math.ceil(cut * fps) - 1) / fps`: for a cut at 23 s in a 30 fps render, `npx hyperframes snapshot --at 22.9667,23 --no-end`. + +## Lighting Lit Meshes + +A `MeshStandardMaterial` lit by one `PointLight` or `DirectionalLight`, with no ambient light, environment map or emissive color, gets no light on its unlit side. When the camera faces that light, the mesh shows only that side and renders as a flat black cutout. Add a fill that stands in for the environment's bounce light, such as a `HemisphereLight` in the colors of the surrounding glow. If the key light's brightness changes over time, drive both lights from the same source at a fixed ratio, tuned by eye. Their intensity units differ, so do not copy the key light's number onto the fill. + ## Good Uses - Deterministic 3D objects, product spins, particles with seeded data, and shader plates.