Cycles OSL Camera - Feedback

Hello everyone,

Over the last few weeks I’ve been working on Cycles support for writing custom cameras using OSL.
This can be used for e.g.:

  • Lens distortion
  • Realistic lens simulation
  • Panorama mappings
  • Custom camera projections
  • many more things, OSL is a powerful programming language after all

It should be pointed out that this is independent from OSL shading (and the associated performance hit), you can use the custom camera scripts without enabling that.

While there still are some limits/TODOs (see below), it’s already usable for initial testing, so I’d be happy to receive feedback on what can be improved to make this as useful and powerful as possible.

Current limits/TODOs

  • Camera scripts are only supported on CPU and OptiX currently
  • Ray differentials are broken, so e.g. the wireframe node will not work properly
  • Inverse mapping is broken, so e.g. the Vector pass will not work properly
  • Many of the builtin camera controls (e.g. sensor size, aperture, focus distance) are not yet exposed to the script, so you need to add your own parameters for those at the moment

How to test

  • Download build from Blender Builds - blender.org
  • Use CPU or OptiX
  • Set Camera to Panorama->Script mode
  • Select either an external .osl file or an internal Text datablock (like you would for the Script node)
  • Set parameters (if your script uses any)
  • Render

Here is a quick example of how to implement a perspective camera to get you started:

shader basic_perspective(float fov = 90.0, output vector pos = 0.0,
                         output vector dir = 0.0, output float T = 1.0) {
  float w = tan(0.5 * fov * (M_PI / 180.0));
  float h = w / (16.0 / 9.0);

  dir = normalize(vector(2.0 * (P.x - 0.5) * w, 2.0 * (P.y - 0.5) * h, 1.0));
}

Essentially, the script’s job is to turn a sensor position into an outgoing ray.
The sensor position (from 0 to 1) is available in P.x and P.y. If you need random numbers (e.g. for aperture sampling), you can find two uniform 0-1 variables in N.x and N.y.
The shader is expected to output a position (named pos) and direction (named dir) for the outgoing ray, as well as a transmission intensity (named T). If you set T to zero, the ray is skipped.
The script can have arbitrary input parameters, which will be displayed in the camera properties. Note that OSL parameter metadata is supported to set UI name, description, slider limits etc. for them.

37 Likes

Pretty cool! Is it possible to sample camera position/direction itself? or this is purely for sensor mapping? With camera data it would be ideal way to perform some screen-space segmentation into different parts of scene without tons of tedious setups