Skip to content

Cameras

Cameras define the viewpoint from which the scene is rendered. Plinken supports perspective and orthographic projections.

local cam = scene:create_camera("Main", "perspective")
-- kind: "perspective" | "orthographic"
PropertyTypeAccessDefaultDescription
namestringr/wCamera name
nearnumberr/w0.1Near clipping plane
farnumberr/w1000Far clipping plane
enabledboolr/wtrueWhether camera is active
positionvec3r/wWorld position
rotationquatr/wOrientation quaternion

Standard 3D perspective with field of view and optional aspect ratio:

local cam = scene:create_camera("Main", "perspective")
cam.fov = math.rad(50) -- vertical FOV in radians
cam.aspect_ratio = 16 / 9 -- nil = use viewport aspect
cam.near = 0.1
cam.far = 500

Parallel projection — no perspective distortion. Useful for 2D overlays, UI, or isometric views.

local cam = scene:create_camera("Ortho", "orthographic")
cam.size = 5.0 -- half-height of the view volume
cam.near = -10
cam.far = 100

Set position and rotation directly, or use look_at for convenience:

cam.position = { x = 0, y = 1.6, z = 5 }
-- Orient toward a target point
cam:look_at(
{ x = 0, y = 1, z = 0 }, -- target
{ x = 0, y = 1, z = 0 } -- up vector (optional, defaults to Y-up)
)

One camera renders the main viewport. Set it with:

scene:set_active_camera(cam)
local active = scene:get_active_camera() -- Camera or nil

For multi-camera setups (e.g. split-screen or picture-in-picture):

scene:set_camera(0, main_cam) -- viewport 0 = main
scene:set_camera(1, side_cam) -- viewport 1 = secondary

Read-only matrices useful for custom rendering, UI projection, or raycasting:

cam.view_matrix -- mat4 (r/o), world-to-camera
cam.projection_matrix -- mat4 (r/o), camera-to-clip
local cams = scene:get_cameras() -- array of all cameras
cam:destroy()
local cam = scene:create_camera("Cinematic", "perspective")
cam.fov = math.rad(35) -- tight, cinematic FOV
cam.position = { x = -3, y = 2, z = 6 }
cam:look_at({ x = 0, y = 1.2, z = 0 })
scene:set_active_camera(cam)
-- Animate camera position over time (in an update callback)
local t = pl.timeline.position
cam.position = {
x = math.cos(t * 0.2) * 6,
y = 2 + math.sin(t * 0.1),
z = math.sin(t * 0.2) * 6,
}
cam:look_at({ x = 0, y = 1, z = 0 })