Skip to content

Recipe Workflow

Brian Wandell edited this page Aug 25, 2026 · 2 revisions

Recipe Workflow

ISET3D renders three-dimensional spectral scenes for use with ISETCam and ISETBio. Every scene is represented by a recipe — a MATLAB object (conventionally thisR) that holds everything PBRT needs to render: camera, film, lights, materials, textures, and the asset tree. The core workflow is always the same four steps:

  1. Create or read a recipe.
  2. Edit it with thisR.set/thisR.get.
  3. Write it out as PBRT text files (piWrite).
  4. Render it through PBRT in Docker and read the result back into ISETCam (piRender).
thisR = piRecipeCreate('chess set');

thisR.set('film resolution',[160 160]);
thisR.set('rays per pixel',32);
thisR.set('n bounces',2);

scene = piWRS(thisR,'render flag','hdr');
sceneWindow(scene);

piWRS — write, render, show — is the helper used in nearly every tutorial: it calls piWrite then piRender then opens the right ISETCam window in one step. See Getting Started for a first walkthrough of this loop, and the iset3d-recipe-workflow skill in the ISET3D repository for the full operational reference — creating a recipe three different ways, looking up thisR.get/set parameter names, piWRS options, and copying/merging recipes.

Where The Files Live

piWrite assembles a self-contained PBRT scene under <piRootPath>/local/<sceneName>/: a main <sceneName>.pbrt file, a <sceneName>_materials.pbrt and <sceneName>_geometry.pbrt that it includes, and subfolders for the data those files reference — geometry/, textures/, skymaps/, spds/, and lens/. A renderings/ subfolder holds the EXR output from PBRT. Everything under local/ is git-ignored scratch space, not a source of truth.

The same recipe can be rendered two ways, controlled by where the Docker container runs — see Local rendering and Remote rendering for the concepts and setup for each.

Editing The Recipe

A recipe's contents — the asset tree, materials, lights, camera, and textures — are inspected and changed almost entirely through thisR.get and thisR.set. A few representative edits:

assetID = piAssetSearch(thisR,'object name','figure_3m');
matName = thisR.get('asset',assetID,'material name');
thisR.set('material',matName,'reflectance',[0 0.5 0]);

thisR.set('asset',assetID,'translate',[-2 0 2]);
thisR.set('asset',assetID,'rotate',[0 0 30]);

Recipes have a tree structure: branch nodes carry position, scale, and rotation, and leaf nodes are objects with a material and a shape. Use thisR.show('assets') or piAssetSearch to find an asset rather than a literal name — asset naming isn't guaranteed to be stable across scene revisions. See t_assets.m for the asset tree in depth, and t_materials.m for material inspection and editing.

Scene Versus Optical Image

What piRender returns depends on the camera's optics, and this trips people up:

  • A pinhole camera (no lens) returns an ISETCam scene — spectral radiance. Use sceneGet, sceneWindow, scenePlot.
  • A camera with a lens (omni, realistic, a human-eye model) returns an oi, an optical image — spectral irradiance at the film or retina. Use oiGet, oiWindow, oiPlot.

thisR.get('optics type') tells you which you'll get back before you render. These two representations and their APIs are ISETCam functionality, documented in the ISETCam wiki's Scene Radiance and Optics and Optical Images pages rather than duplicated here.

Render Types

piRender/piWRS can return more than radiance. thisR.set('render type',...) (or the 'render type' option to piWRS) accepts radiance, depth, material labels, instance labels, and illuminance, individually or combined:

thisR.set('render type',{'radiance','depth'});
scene = piWRS(thisR);
scenePlot(scene,'depth map');

Where To Go Next

  • Getting Started for the five-minute setup and first render.
  • The iset3d-recipe-workflow skill for the complete API reference.
  • t_piIntro_chess.m and the rest of the introduction tutorial path for a guided first pass.

Clone this wiki locally