Most mistakes in 3D code are unit mistakes. This page lists every convention in one place.
Axes#
Apricot uses three.js's right-handed coordinate system:
| Axis | Positive direction (default camera) |
|---|---|
x |
right |
y |
up |
z |
towards the viewer (out of the screen) |
The ground is the x–z plane at y = 0.
The default camera#
| Setting | Default |
|---|---|
position |
[0, 0, 6]: 6 units in front of the origin |
target |
[0, 0, 0]: it looks at the origin, down the −z axis |
fov |
50 degrees (vertical field of view) |
near, far |
0.1 and 200: raise far for big scenes |
Change it with <Scene camera={{ position, target, fov, near, far }}> (read once at mount), or move it at runtime with <CameraRig>.
Which way objects face#
- Models face +z: their front looks at the default camera. In joints and hinges,
frontis +z,topis +y andleftis +x (the model's own left, as it faces you). <Plane>faces +z (a wall facing you). For a floor, rotate it:rotation={[-Math.PI / 2, 0, 0]}.<Cylinder>,<Cone>and<Capsule>stand along y.<Torus>lies in the x–y plane (a ring facing you).<Car>(from@apricot/assets) and<Vehicle>face +z; a heading of0drives towards +z.
Units#
| Quantity | Unit | Examples |
|---|---|---|
| Distance, size | scene units, meant as metres | position, size, radius, Path distances, Vehicle speeds (units/s), shadow radius |
| Object rotation | radians, Euler [x, y, z] (XYZ order) |
rotation on every object, Instances items, Vehicle heading |
| Rotation speed | radians per second | <Spin speed> |
| Camera angles | degrees | azimuth, elevation, fov, orbit turn and elevation limits, drift (degrees per second) |
| Joint angles | degrees | joint range |
| Light cone | radians | <SpotLight angle> |
| Time | seconds | transition, duration, dwell, linger, delta in useFrame |
| Screen space | points (React Native units) | inset, <Blur radius>, Label layout |
| Time of day | hours, 0–24 | <Daylight time={13.5}> |
| Progress | 0 to 1 |
joint values (0 closed, 1 open), animation clip progress, morph weights |
Why metres matter#
Lights, fog, shadows and physics are tuned for real-world sizes. A product is about 0.1–3 units, a car about 4, a building 10–100, a map 1000+. If a scene looks wrong, check the scale first:
- Objects look tiny or huge: the camera distance does not match the object size. Use
<FitCamera>or<CameraRig>, which frame the subject automatically. - Things vanish in the distance: raise
camera.far(default 200). - Shadows look blocky in a big scene: give
shadows={{ radius }}in metres around what the camera looks at.
Camera views#
<CameraRig> places the camera on an orbit around its subject:
| Field | Meaning |
|---|---|
azimuth |
Degrees around the vertical axis. 0 looks at the front (camera on +z), 90 at the left side (camera on +x), 180 at the back, -90 at the right side. |
elevation |
Degrees above the horizon. 0 is level, 90 looks straight down. |
distance |
Units from the target. Leave it out to fit the subject on screen. |
target |
The point looked at. Default: the subject's centre. |
position |
An exact camera position, instead of the angles. |
fov |
Vertical field of view in degrees. |
Built-in views: front (0°, 8°), back (180°, 8°), left (90°, 8°), right (−90°, 8°), top (0°, 90°) and three-quarter (35°, 16°), given as azimuth then elevation.
Colours#
Anything three.js accepts as a colour: a CSS string ("#ff9f59", "rgb(255, 159, 89)", "tomato") or a number (0xff9f59). Colours are in sRGB, as you would pick them in a design tool.
Related#
- Objects and refs: positions are relative to the parent.
- Camera guide.