The camera statement says where the viewer is, how the picture is projected and how big the view is. A scene needs one; with none, the default camera is used. If a scene has more than one camera statement, the last one is used and the parser prints the warning “More than one camera in scene. Ignoring previous camera(s).” A camera is described by a projection type, four vectors (location, direction, right, up), and modifiers (angle, look_at, sky, focal blur, a normal, transformations).
Syntax
camera {
[camera identifier]
[perspective | orthographic | fisheye | ultra_wide_angle | omnimax | panoramic |
cylinder 1..4 | spherical | mesh_camera { … } | user_defined { … }]
[location <v>] [direction <v>] [right <v>] [up <v>] [sky <v>]
[angle horizontal [, vertical]] [look_at <v>]
[aperture a] [blur_samples [min,] max] [focal_point <v>]
[confidence c] [variance v] [bokeh { pigment { … } }]
[normal { … }]
[translate | rotate | scale | transform | matrix …]
}
The projection type, if written, must come first. All other items may be written in any order (see below for how the parser applies them). A projection type word that comes after other items is the error “Expected … camera modifier”. When no type is written the camera is a perspective camera.
For mesh_camera and user_defined the parser turns on an “experimental feature” flag and the program prints a warning at the end of parsing.
Defaults and the default camera
| Keyword | Value | Default | Meaning |
|---|---|---|---|
| type | perspective | ||
location | vector | <0, 0, 0> | the position of the camera |
direction | vector | <0, 0, 1> | the initial viewing direction. Its length is the distance of the view plane from the camera: shorter is wider, longer zooms in. It is changed by angle and look_at |
right | vector | <w/h, 0, 0> (<1.33, 0, 0> before language version 3.8) | the width and the direction to the right of the view plane. w/h is the aspect ratio of the image (+W and +H or Width and Height). A negative x makes the coordinate system right-handed |
up | vector | <0, 1, 0> | the height of the view plane |
sky | vector | <0, 1, 0> | the direction that look_at treats as up. It does nothing without look_at |
look_at | vector | <0, 0, 1> | point the camera at this point |
angle | degrees | from direction and right: about 67.38 for the default vectors and a 4:3 image | horizontal viewing angle, see below |
aperture | number | 0 (no focal blur) | size of the aperture for focal blur |
blur_samples | [min,] max | 0 | number of sample rays per pixel for focal blur |
focal_point | vector | the point at the distance of the length of direction (<0, 0, 1>) | centre of the zone of sharpness |
confidence | number, 0 < c < 1 | 0.9 | for the adaptive sampling of focal blur |
variance | number, 0 to 1 | 1/10000 | tolerance of the variance of the samples |
bokeh | { pigment { … } } | none | shape of the blur |
normal | normal | none | perturbs all camera rays |
The default camera is the same as camera { perspective location <0,0,0> direction <0,0,1> right <w/h,0,0> up y sky y }. Without a #version directive the scene has language version 3.62, so right is <1.33, 0, 0> for the default camera.
The manual gives a variance default of 1/128 and a focal point default of <0,0,0>; the source of the camera class (source/core/scene/camera.cpp) has 1/10000 and <0,0,1>, which is what this page lists. The focal point only matters through its distance from the location: if no focal_point is written, the focal distance is the length of the direction vector (1 if that is 0).
Location, direction, right, up, angle and look_at
- Order of application. From language version 3.5 the parser applies the items in a fixed order, whatever the order in the text:
right,direction,angle,up,sky,location,look_at,focal_point, then the transformations. Solook_atmay stand anywhere, andanglealways sees the finalright. Before 3.5 the items took effect one by one in the order written andlook_athad to be last. - angle. For
perspectiveandorthographicthe length ofdirectionis changed to|right| / (2 × tan(angle / 2))(the direction vector is normalised first). The angle must be smaller than 180: “Viewing angle has to be smaller than 180 degrees.” A negative angle is the error “Negative viewing angle.” The other types store the angle and use it as in the table below. An angle of 0 does not change the direction. - look_at. The direction becomes
look_at − location, normalised and then given the old length. The newrightissky × direction(normalised, with the old length ofright; its sign keeps the old handedness) andupisdirection × right(with the old length ofup). If the direction is parallel toskythere is a warning and the previousrightis used. If location and look_at are equal: “Camera location and look_at point must be different.” - Perpendicular vectors.
direction,upandrightshould be perpendicular. If not, the parser warns “Camera vectors are not perpendicular. Making look_at the last statement may help.” and the image is distorted. - Aspect ratio. The ratio of the lengths of
rightandupis the aspect ratio of the picture. Set it from the image size:right x*image_width/image_height(the default from language version 3.8). For a fisheye camera an elliptical picture instead of a circle means the aspect ratio does not match the image. - Handedness. POV-Ray is left-handed by default (x to the right, y up, z into the picture).
right -x*image_width/image_heightwith the camera at positive z makes it right-handed. - Transformations.
translate,rotate,scale,transformandmatrixmove the finished camera. They are applied in the order written, after everything else.
Projection types
| Keyword | Projection | What angle, direction, right and up do |
|---|---|---|
perspective | pinhole camera; the default | the horizontal angle is set by angle or by the length of direction compared with right; must be less than 180 degrees. Vista buffers work with this type |
orthographic | parallel rays | two modes. With up or right written (and no angle) the lengths of up and right are the size of the window and the length of direction is not used. With no up and right, or with angle (a number is optional: angle alone also counts), up and right are scaled so that the image area at the look_at point equals that of the perspective camera. Objects behind the plane through location disappear |
fisheye | spherical projection onto a circle | angle is the angle of the circle: 180 is the usual fisheye, 360 a “see everything” view. The lengths of direction, up and right do not matter |
ultra_wide_angle | like fisheye, onto a rectangle | angle is the horizontal angle; the vertical angle follows from the ratio of the lengths of up and right. For a ratio of 1 a square is wrapped on the surface x² + y² + z² = x²y² + 1. The angle may be over 180 (even 360 with up/right in a ratio 1/2 gives a full view with the zenith at the top). Angles over 180 in both directions wrap the corners more than once |
omnimax | a 180 degree fisheye with a smaller vertical angle, for dome theatres | angle is not used (the parser reads it); the ratio of up and right counts. The picture looks elliptical |
panoramic | cylindrical equirectangular projection; allows angles over 180 | the manual says that angle is irrelevant and that the lengths of direction, up and right are the three axes of an ellipsoid; with equal lengths and perpendicular vectors it equals spherical with angle 180, 90. Use a direction of length 1 |
cylinder n | projection onto a cylinder; n is 1 to 4, anything else is the error “Invalid cylinder camera type, valid are types 1 to 4.” | 1: vertical cylinder (axis along up), fixed viewpoint. 2: horizontal cylinder (axis along right), fixed viewpoint. 3: vertical cylinder, the viewpoint moves along the axis (all rays are perpendicular to the axis; the length of up is the height in units). 4: horizontal cylinder, the viewpoint moves along the axis. The width follows from right or from angle. Use a direction of length 1 |
spherical | rectangular (latitude-longitude) projection onto a sphere, like map_type 1 | angle h [, v]: horizontal angle, and a vertical angle that defaults to half of h. Both up to 360. Negative values are errors. Default angles when none is written: 360 and 180. The lengths of the vectors do not matter. An image of 2:1 mapped onto a sphere with map_type 1 restores the scene (environment maps) |
mesh_camera | rays are taken from the faces of a mesh | see below. Experimental |
user_defined | ray origin and direction are given by functions | see below. Experimental |
mesh_camera
mesh_camera {
rays_per_pixel distribution [max_distance]
mesh { … } | mesh2 { … } [mesh …]
[smooth]
}
[location <v>] [direction <v>]
The first two numbers are not separated by a comma (a comma is a parse error). Each pixel is assigned to a face of a mesh; the ray starts at the centre of the face and goes along its normal (distribution 3 uses a point of the face found from its UV coordinates). location and direction have a special meaning: the z of location moves the ray origin along the normal of the face, and a negative z of direction (less than −EPSILON) reverses all rays.
| Item | Value | Meaning |
|---|---|---|
| rays_per_pixel | integer ≥ 1 | rays shot for each pixel; the results are averaged. 0 is the error “Rays per pixel may not be 0” |
| distribution | 0, 1, 2 or 3 | 0: ray number n of a pixel uses mesh n and the face with the number of the pixel (needs at least as many meshes as rays per pixel). 1: the faces of all meshes are counted as one list; the extra rays of a pixel use the face at width × height × ray_number + pixel_number. 2: a horizontal row of sub-cameras, one per mesh (for stereo); one ray per pixel. 3: the face is found from the UV coordinates of the pixel (so antialiasing works; for texture baking; the mesh needs UV coordinates); one ray per pixel; only the first mesh is used. Methods 2 and 3 need rays per pixel 1: “Rays per pixel must be 1 for distribution method #2 or #3”. Another number is “Unrecognized distribution method” |
| max_distance | number | optional; if larger than EPSILON no object farther than this from the ray origin is hit (to probe a scene). Default 0, no limit |
mesh, mesh2 | object | one or more meshes, with transformations allowed. None: error. For distribution 0 the number of rays per pixel must not exceed the number of meshes |
smooth | only for distribution 3: the ray direction is interpolated like on a smooth triangle (the mesh needs normals). Another distribution is the error “Smooth can only be used with distribution method #3”. In this source it is parsed inside the braces of mesh_camera, after the meshes |
Ordinary antialiasing and jitter do not make sense for distributions 0, 1 and 2, because the pixel position is turned into an integer for the face index; the program gives no warning.
user_defined
user_defined {
[location { function { … }, function { … }, function { … } } | location <v>]
[direction { function { … }, function { … }, function { … } } | direction <v>]
}
The three functions take the screen position x, y (also called u, v) as parameters. The coordinates run from −0.5 (left and bottom) to 0.5 (right and top). Each triple of functions gives the ray origin (location) and the ray direction (direction). Where a triple is not written, the plain vector is used (the default location is the origin and the default direction is <0, 0, 1>), and the ordinary items (look_at, transformations) work. angle is an error in this camera type. The type can copy the others and is meant for light probes, angular, cube-map, side-by-side stereo, omni-directional stereo and map projections.
Focal blur
Depth of field is simulated by shooting several rays from jittered points of the aperture and averaging. It is turned on when aperture is greater than 0 and blur_samples is set; the default is no blur.
| Keyword | Value | Meaning |
|---|---|---|
aperture | number | the size of the aperture. A large value blurs a lot and gives a narrow zone of sharpness. The values are not f-stops |
blur_samples | [min,] max | the maximum number of rays per pixel, and optionally the minimum number taken before the adaptive test starts. Values of 0 or less are the error “Illegal number of focal blur samples.”; a minimum larger than the maximum is an error. With only one number the minimum is not given (the manual says the program then uses 4 for a maximum below 7 and 7 otherwise). With 4, 7, 19 or 37 samples the bokeh is square; other numbers use a Halton sequence and a round bokeh |
focal_point | vector | a point of the plane of focus. The plane goes through it and is parallel to the camera |
confidence | number from 0 to less than 1 | probability that the estimated colour is close to the real colour; shooting stops then. Default 0.9. A larger value gives more samples. A value outside the range gives the warning “Illegal confidence value. Default is used.” |
variance | number from 0 to 1 | accepted variance of the samples; about the smallest colour difference that matters. Default 1/10000. A value outside the range is a warning. A lower value gives smoother, slower images (1/10000 with 100 samples is a good result) |
bokeh | { pigment { … } } | sample the aperture with the brightness of the pigment in the unit square of the x-y plane (<0,0,0> to <1,1,0>), which sets the shape of out-of-focus highlights |
Ray perturbation
normal { bumps 0.5 } in the camera perturbs all camera rays with a normal pattern; the image looks as if seen through bumpy glass (see Normals and finishes).
Camera identifiers
A camera can be declared with #declare Name = camera { … } (or #local) and used as camera { Name }. From language version 3.5 the only items that may follow the identifier are transformations (translate, rotate, scale, transform, matrix); keywords that change the behaviour of the camera (angle, location …) are not allowed, because the parser has to resolve their order first. The transformations of the identifier are kept, and the new ones are added after them. Camera identifiers can be used to switch between views with one line.
stdcam.inc and screen.inc
stdcam.inc is a ready-made scene start, not a set of macros. Including it creates a camera (location <-2, 1.75, -5>, right x*1.3333, angle 70, look_at <-0.75, -0.5, 0>), a light source at <20, 20, -25> and a plane y, 0 with the pigment Plum (from colors.inc, so include that first).
screen.inc puts objects and textures in front of the camera, for logos and signatures. It works with the perspective camera and creates the camera itself when it is included. These identifiers and macros exist:
| Name | Meaning |
|---|---|
Update_Camera() | (re)creates the camera and the transform Camera_Transform from the settings below. Called by the macros that follow, so every call writes a new camera statement (hence the warning about more than one camera) |
Camera_Location, Camera_Look_At, Camera_Sky, Camera_Zoom, Camera_Aspect_Ratio | the settings; defaults <0,0,0>, z, y, 1 and image_width/image_height |
Set_Camera_Location(loc), Set_Camera_Look_At(p), Set_Camera_Sky(s), Set_Camera_Zoom(z), Set_Camera_Aspect_Ratio(r), Set_Camera_Aspect(w, h) | set one value and update the camera |
Set_Camera_Angle(a) | sets the zoom to 0.5 / tan(radians(a / 2)) × Camera_Aspect_Ratio |
Set_Camera(loc, look_at, angle) | location, look_at and angle in one call |
Reset_Camera() | forgets all the settings and restores the defaults |
Screen_Object(object, position, spacing, confine, scaling) | places an object in screen space: position is a 2D vector in the unit square (0 to 1, from the bottom left), spacing a margin, confine 0 or 1 keeps the object inside the picture, scaling scales it. The object gets no_shadow, no_reflection and no_radiosity |
Screen_Plane(texture, scaling, bl_corner, tr_corner) | a flat box in front of the camera with a texture, between two corners given in the unit square; it is hollow (for fog and media) and also has no_shadow, no_reflection |
Objects placed by screen.inc are still part of the scene: they are lit, and affected by perspective. See Include files.
Examples
#declare Cam_Perspective = camera {
perspective
location <3, 5, -10>
sky <1, 1, 0>
angle 50
look_at <0, 2, 1>
}
#declare Cam_Orthographic = camera {
orthographic
location <0, 5, -5>
look_at 0
angle 30
}
#declare Cam_Ortho_Window = camera {
orthographic
location <0, 0, -5>
right 4*x
up 3*y
look_at 0
}
camera {
Cam_Perspective
translate <1, 0, 0>
}
sky. The first orthographic camera has the image area of a perspective camera at the look_at point; the second has a window of 4 by 3 units.#declare Cam_Fisheye = camera { fisheye location <0, 0, -3> look_at 0 angle 180 }
#declare Cam_Ultra = camera { ultra_wide_angle location <0, 0, -3> look_at 0 angle 240 right 20*x up 10*y }
#declare Cam_Omnimax = camera { omnimax location <0, 0, -3> look_at 0 }
#declare Cam_Panoramic = camera { panoramic location <0, 0, -3> look_at 0 }
#declare Cam_Spherical = camera { spherical location <0, 0, -3> angle 360, 180 }
#declare Cam_Cylinder1 = camera { cylinder 1 location <0, 0, -3> look_at 0 angle 120 }
#declare Cam_Cylinder4 = camera { cylinder 4 location <0, 0, -3> angle 90 }
camera { Name } follows).camera {
location <0, 2, -6>
look_at 0
aperture 0.3
blur_samples 4, 20
focal_point <0, 0, 0>
confidence 0.95
variance 1/10000
bokeh { pigment { radial color_map { [0 rgb 1] [1 rgb 0] } } }
normal { bumps 0.02 scale 0.1 }
}
#declare Grid = mesh {
triangle { <-1, -1, 0>, <1, -1, 0>, <1, 1, 0> }
triangle { <-1, -1, 0>, <1, 1, 0>, <-1, 1, 0> }
}
camera {
mesh_camera {
1 0
mesh { Grid translate <0, 0, -4> }
}
location <0, 0, 0>
direction <0, 0, 1>
}
#declare Cam_Ortho_UD = camera {
user_defined
location {
function { x * 4 }
function { y * 4 }
function { -5 }
}
direction {
function { 0 }
function { 0 }
function { 1 }
}
}
#declare Cam_Pinhole_UD = camera {
user_defined
direction {
function { x }
function { y }
function { 1 }
}
location <0, 0, -3>
rotate y*5
}
camera { Cam_Ortho_UD }
#include "screen.inc"
Set_Camera(<0, 2, -6>, <0, 0, 0>, 50)
Screen_Plane(texture { pigment { rgbf <1, 1, 0, 0.5> } }, 0.1, <0.05, 0.05>, <0.25, 0.15>)
Set_Camera. The include file creates a camera when it is read and each macro call creates another, so the parser warns that earlier cameras are ignored.Not described
Known, not yet covered
- Reference: the exact ray equations of the fisheye, ultra wide angle, omnimax, panoramic and cylinder cameras (
source/core/render/trace.cppand the camera ray code) are described by the manual’s words only. The old (before 3.5) order-dependent syntax is mentioned but not listed keyword by keyword. - Reference: the manual lists the vista buffer as available for perspective and orthographic cameras only; that is not covered here.