Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

After the displacement has been done, any smooth analytical normals that the original surface may have had (for example a smooth subdivision surface or NURBS patch) are no longer valid – they do not correspond to the displaced surface.  However, each micropolygon has a geometric normal Ngn.  In addition, for some surface types, a smooth shading normal will be automatically computed for each ray hit – this is done by considering the orientation of not only the micropolygon that the ray hit, but also adjacent micropolygons.  For other surface types – most prominently displaced polygon meshes and displaced pretessellated subdivision surfaces – the shading normal is the same as the geometric normal, i.e. facetted.  (We plan to provide smooth shading normals also on these surface types in a future release.)

Displacement bounds

In order to ray trace a scene efficiently, RenderMan needs to know where the objects are.  Objects are organized into a ray acceleration data structure: a bounding volume hierarchy (BVH) where each node in the hierarchy is a bounding box for the objects below it in the hierarchy.  For displaced surfaces computing these bounding boxes is a bit tricky because we don't know where the surface points actually are until the displacement shader has run.  But we don't want to run the displacement shader on all displaced surfaces before tracing the first rays – if we did, the time-to-first-pixel would suffer.  What we need is a rough indication of how large the the displacement might be, without the expense of running the displacement shader to determine the exact displacement.  Such an indication must be provided with a displacement bound for each displaced object; the displacement bound is an upper limit on the displacement on that object.  For example, if we know that the maximum magnitude of displacement on a given object is 0.5 units, then we can specify the displacement bound like this:

...

shader
dispstar(float scale = 1.0, float freq = 5.0,
         output float resultF = 0.0)
{
  vector Non;   // original, undisplaced normal
  getattribute("builtin", "Non", Non);  // Convert Non from current (world) space to object space
  vector Nobj = transform("object", Non);

  // Compute displacement amount

  float angle = atan2(NobjN[1], NobjN[0]);

  float disp = scale * sin(freq*angle);

...