Core concepts
Virtual cameras
A virtual camera is a shot you might want to show. You can have as many as you like. Klipp decides which one is on screen:
- the active camera with the highest
prioritywins, - an inactive camera is out of the running completely,
- when the winner changes, Klipp blends from the old shot to the new one.
Building a shot
Each camera is made of up to four kinds of pieces, which run in this order every frame:
A few Extensions run earlier, because the Body or Aim works with what they set: Lens runs first, and FollowZoom and Confiner right after the Body. See Extensions.
Body and Aim are independent, so a camera can follow one object while looking at another. Every piece is optional: a camera without an Aim keeps its starting rotation.
One piece in every integration
Every piece is a core class. Integrations adapt it to their world: in three.js, FollowBodyThree is FollowBody reading Object3D targets, and the React <Body.Follow> creates one for you. Settings have the same names everywhere.
Targets
Pieces follow and look at targets:
- Core: the core doesn't know about your scene. A target is a
TargetPoseyou keep up to date from wherever your data lives:position, androtationwithhasRotation. Pieces that frame by size, like the composers, also read itsextent. - three.js and React Three Fiber: a target is an
Object3D, a ref to one, or a fixed point: aVector3or[x, y, z]. Objects are tracked live, including their rotation.
A target of null, or a ref that is still empty, is ignored until it resolves.
Damping
Most pieces take a damping setting that makes them ease toward their goal instead of snapping to it. It's a time in seconds: 0 is instant, 0.5 feels smooth, 2 feels heavy.
Pass { into, from } to ease differently while the gap is growing (into) and while it's closing again (from).
Next to damping you'll usually find maxSpeed, which caps how fast the camera may move while catching up.
Changing settings while running
Settings are plain fields, so you can change them at any time, even every frame. Vector fields are always [x, y, z] arrays. In React, ref gives you the piece itself, so you can change it without re-rendering.
Usage
Feeding a target:
import { quat, vec3 } from 'math';
import { targetPose } from '@pmndrs/klipp';
const player = targetPose.create();
player.extent.radius = 0.5; // for pieces that frame by size
// every frame, before klipp.update
vec3.copy(player.position, playerPosition);
quat.copy(player.rotation, playerRotation);
player.hasRotation = true;
new HardLookAtAimThree(player); // an Object3D
new HardLookAtAimThree({ current: player }); // a ref to one
new HardLookAtAimThree(new Vector3(0, 1, 0)); // a fixed point, or [0, 1, 0]
<Aim.HardLookAt target={playerRef} /> // a ref to an Object3D
<Aim.HardLookAt target={player} /> // an Object3D
<Aim.HardLookAt target={[0, 1, 0]} /> // a fixed point, like <mesh position>
Ready to build one? Continue with Your first camera.