Camera, light and fog

Aim, follow and shake the camera, and light and color the scene.

Perspective and orthographic

A Camera has mutable eye and target tuples and a vertical fov in radians. ortho (half the visible height in world units) makes it orthographic and overrides fov.

Mutate the object from onUpdate; GameView reads it every frame. Keep a tiny offset for straight-down views so eye and target never align vertically.

Two cameras

React and React Native · shared engine API

Two cameras
import type { Camera } from "@nayan-ui/engine";
export const perspective: Camera = { eye: [8, 6, 12], target: [0, 1, 0], fov: Math.PI / 3 };
export const board: Camera = { eye: [0, 20, 0.01], target: [0, 0, 0], fov: 1, ortho: 6 };
export function orbit(camera: Camera, time: number) {
camera.eye[0] = Math.sin(time) * 12;
camera.eye[2] = Math.cos(time) * 12;
}

Follow and shake

camera.follow = { target, offset, smoothing? } eases the target toward the entity's drawn position and keeps the eye at offset. smoothing is roughly the catch-up time in seconds (default 0.15, 0 is rigid); null returns control.

camera.shake is a strength in world units that fades by itself.

Chase and hit feedback

React and React Native · shared engine API

Chase and hit feedback
import type { Camera, Entity } from "@nayan-ui/engine";
export function chase(camera: Camera, player: Entity) {
camera.follow = { target: player, offset: [0, 4, 7], smoothing: 0.12 };
}
export function onHit(camera: Camera) {
camera.shake = 0.3;
}
export function release(camera: Camera) {
camera.follow = null;
}

Directional light

One directional light with ambient fill and a shadow map centred on the camera target. A small shadowExtent clips distant shadows; a large one blurs them.

Directional light reference
Light fieldBehavior
directionToward the light; need not be normalized.
ambient0..1 ambient term.
colorCSS or tuple multiplying sun and ambient; glowing colors unaffected.
shadowsCast shadows; default true.
shadowExtentHalf-size of the shadowed area in world units; default 30.

Moonlit scene

React and React Native · shared engine API

Moonlit scene
import { GameView, type Light, type World } from "@nayan-ui/engine";
const moon: Light = { direction: [-0.5, 0.8, 0.3], ambient: 0.3, color: "#5A61A0", shadowExtent: 24 };
export function Night({ world }: { world: World }) {
return <GameView source={world} light={moon} background="#0B1020" style={{ flex: 1 }} />;
}

Background and fog

background is the clear color (CSS or tuple, alpha ignored; default dark navy) and also the fog color. fog is the density toward it, such as 0.02; default 0.

Hazy horizon

React and React Native · shared engine API

Hazy horizon
import { GameView, type World } from "@nayan-ui/engine";
export function Haze({ world }: { world: World }) {
return <GameView source={world} background="rgb(200, 215, 230)" fog={0.03} style={{ flex: 1 }} />;
}

Flat boards with frontLight

frontLight(direction, ambient) lights camera-facing surfaces at exactly 1, so flat tiles show their exact theme color while rounded shapes keep shading. It turns shadows off; pair it with a camera looking down -z.

Puzzle board

React and React Native · shared engine API

Puzzle board
import { GameView, frontLight, type World } from "@nayan-ui/engine";
const light = frontLight([-0.45, 0.6, 1], 0.5);
export function Board({ world }: { world: World }) {
return (
<GameView source={world} light={light} background="#F4F1EA" style={{ flex: 1 }}
camera={{ eye: [0, 0, 50], target: [0, 0, 0], fov: 1, ortho: 10 }} />
);
}

Colors and toColor

Every color option takes '#RGB', '#RGBA', '#RRGGBB', '#RRGGBBAA', 'rgb(…)', 'rgba(…)', a name (transparent, black, white, red, green, blue, yellow, orange, purple, gray, grey) or a 0..1 tuple. Tuple channels above 1 glow, and at 2 ignore light and shadow.

toColor(color, alpha?) returns the [r, g, b, a] tuple, for when you need the numbers. Unknown strings throw.

Brighten a theme color

React and React Native · shared engine API

Brighten a theme color
import { toColor, type World } from "@nayan-ui/engine";
const [r, g, b] = toColor("#FF4757");
export const ember = [r * 2, g * 2, b * 2] as const; // self-lit glow
export const ghost = toColor("#FF4757", 0.4); // see-through
export function addLamp(world: World) {
return world.spawn({ mesh: "sphere", color: ember, position: [0, 3, 0] });
}