# Writing Integrators

### The Interface

RixIntegrator.h describes the interface that integrators must implement and is required by all RixIntegrator plugins.

### About Ray Differentials & Ray Spreads

#### Ray Differentials

Ray differentials determine texture filter sizes and hence texture mipmap levels (and texture cache pressure in scenes with many textures).

In RIS the goal for ray differential computation was improved efficiency (over REYES), even if it's not going to give quite as accurate ray differentials in all cases. Auxiliary ray-hit shading points are no longer created, and we only compute an isotropic ray "spread" - not a full anisotropic set of ray differentials. The ray spread expresses how much the ray gets wider for every unit of distance it travels.

#### Camera Ray Spread

By default, the spread of camera rays is set up such that the radius of a camera ray is 1/4 pixel. The width of the camera ray is two times its radius, ie. 1/2 pixel. Footprints are constructed at ray hit points such that a camera ray hit footprint is 1/2 pixel wide. Equivalently, the area of a camera ray footprint is 1/4 pixel. (This is true independent of image resolution and perspective/orthographic projection.)

This choice of default camera ray spread has both a theoretical and a practical foundation. Theory: footprints that are 1/2 pixel wide match the Nyquist sampling limit. Practice: our experiments indicate that footprints smaller than 1/2 pixel wide do not sharpen the final image, but footprints wider than that do soften the final image. Moving to smaller than 1/2 pixel width is all pain (finer mipmap levels, more texture cache pressure), no gain (no image quality improvement). Moving to wider than 1/2 pixel is more subjective: some people prefer the sharp look, some prefer the softer look.

#### Reflected Ray Spread

For reflection we compute the reflected ray spread using two approaches:

1. Ray spread based on surface curvature.

The ray spread for reflection from a curved smooth surface is simple to compute accurately using Igehy's differentiation formula:

```spread' = spread + 2*curvature*PRadius
```
2. Ray spread based on roughness (pdf).

The ray spread from a flat rough surface depends on roughness: the higher the roughness the lower the pdf in a given direction; here we map the pdf to a ray spread using a heuristic mapping:

```spread' = c * 1/sqrt(pdf) -- with c = 1/8
```

We set the overall ray spread to the max of these two.

This ray spread computation is done in the SetRaySpread() function (see RixIntegrator.h), which is called from the various RIS integrators. Integrator writers can easily make their own version of SetRaySpread() using other techniques and heuristics and call that from their integrators.