自定义摄像机

In addition to the built-in camera types (Perspective, Orthographic and Panoramic cameras), Cycles also supports implementing custom cameras using Open Shading Language (OSL).

Custom cameras are implemented as OSL shaders. A camera shader receives a sensor position as its input and outputs the corresponding ray's position, direction and throughput.

OSL for shading and custom cameras are independent, so the latter can be used even when OSL shading is disabled.

使用自定义摄像机

In order to use a custom camera, set the lens type to Custom.

This enables the selection of a text data-block or external file, similar to the Script node in shaders.

If the selected camera shader has parameters, they will be displayed below the Lens panel.

编写摄像机着色器

输入

The primary input to the camera shader is the sensor position. This is provided by the function camera_shader_raster_position(), which returns a point whose X and Y components store the position within the image in the range of 0-1.

In order to support random sampling in the shader, a pair of random numbers is provided by camera_shader_random_sample(), which returns a vector containing random numbers in its X and Y components. For the particular case of sampling the aperture, it's better to use the cam:aperture_position attribute (see below) to be compatible with Blender's usual aperture options.

输出

The shader is expected to output three variables:
  • position, a variable of type point which contains the origin of the generated ray.

  • direction, a variable of type vector which contains the normalized direction of the generated ray.

  • throughput, a variable of type color which contains the throughput of the ray - a weighting factor

that can be used to dim or tint the resulting color seen by the camera.

Both position and direction are in camera coordinates, where the origin is the position of the camera itself, the positive Z axis is the view direction, and the positive Y axis is up.

If throughput is black, the resulting ray is skipped. This can be used to e.g. indicate invalid rays for panoramic mappings.

属性

Since camera shaders are not shaders in the traditional sense, many of OSL's features such as closures or geometry-related attributes are not available.

Instead, the following camera-specific attributes are available through getattribute():

cam:sensor_size

Size of the camera sensor in millimeters, as set in the Camera properties.

cam:image_resolution

Resolution of the rendered image.

cam:focal_distance

Focal distance of the camera in millimeters, as set in the Depth of Field properties.

cam:aperture_aspect_ratio

Aspect ratio of the camera aperture, as set in the Depth of Field properties.

cam:aperture_size

Size of the camera aperture, as set in the Depth of Field properties.

cam:aperture_position

A random position on the aperture, taking into account its size, shape and aspect ratio as set in the Depth of Field properties. Note that this uses the same random numbers as provided by camera_shader_random_sample(), so avoid using both as it would lead to correlation issues.

Derivatives

For some features such as the Wireframe node, Cycles needs derivatives of the ray origin and direction with respect to image X and Y coordinates.

By default, OSL auto-differentiation will be used to compute these. For advanced cases where you can compute the derivatives more accurately or efficiently, you can make your shader output four additional variables named dPdx, dPdy, dDdx and dDdy. If any of these are present, their values will be used instead. Note that you can not mix both options - either all or none must be explicitly provided.

参数

Shaders can define additional input parameters. These will be exposed to the user in the Camera properties panel, under the Lens options.

To further control how they are presented, the following OSL metadata can be used:

[[ string help = "This is a parameter" ]]

Description of the parameter, shown in the tooltip.

[[ float sensitivity = 0.25 ]]

How far to increment/decrement the parameter when dragging/clicking.

[[ int digits = 2 ]]

How many digits are displayed for numerical parameters.

[[ float min = -5, float max = 5 ]]

What range the property can take on.

[[ int slider = 1, float slidermin = -4, float slidermax = 4 ]]

Display the property as a slider with the given range.

[[ string widget = "boolean" ]]

Display the `int` property as a checkbox, resulting in values 0 or 1.

一个例子

这是一个实现透视摄像机的非常基本的着色器:

shader perspective_camera(
    float focal_length = 90.0 [[ float sensitivity = 0.2, float min = 0 ]],
    output point position = 0.0,
    output vector direction = 0.0,
    output color throughput = 1.0) {
  vector sensor_size;
  getattribute("cam:sensor_size", sensor_size);

  point Pcam = camera_shader_raster_position() - point(0.5);
  Pcam *= sensor_size / focal_length;
  direction = normalize(vector(Pcam.x, Pcam.y, 1.0));
}

更多示例可在此找到:文本编辑器 ‣ 模板 ‣ 开放式着色语言

局限

Important

自定义摄像机不支持 GPU 渲染,除非使用 OptiX 后端。

Cycles 中的某些功能(特别是矢量通道和窗口纹理坐标)需要从光线到图像坐标的逆映射。目前自定义摄像机尚不支持此功能。