Smooth Derivatives in PhotoRealistic RenderMan

Smooth Derivatives in PhotoRealistic RenderMan

August 1998

Introduction

As described in the RenderMan specification, the derivative functions (Du(), Dv(), Deriv()) and surface differentials (du, dv) describe how much of the surface the current shading element represents. The shading system uses these functions and values internally for filtering, and shader writers may take advantage of them when writing shaders that antialias themselves.

Because PhotoRealistic RenderMan is a micropolygon-based renderer, it has always based its derivatives and differentials on the current micropolygon size; that is, if the micropolygon subtends a certain range in u and v, the derivatives will reflect a shading element of exactly that size. This is an intuitive representation of the derivatives, but can sometimes introduce subtle filtering artifacts when adjacent regions of an object have been diced at different rates. We seek a shading element size which is independent of the actual dicing rate of the object.

Recall that PRMan's "shading rate" attribute indicates the desired micropolygon size in screen space; the renderer will try to achieve this rate when dicing a primitive into micropolygons, but rarely hits it exactly. Across a shading grid, some micropolygons may project to slightly larger than the "perfect" size, and some may be slightly smaller. As a result, micropolygons on adjacent grids may have significantly different sizes, and this leads to discontinuities in the derivative functions.

PRMan 3.8 introduced a method to compute surface derivatives and differentials that is independent of the actual dicing rate of the object. The renderer now estimates the size of a "perfect" micropolygon (one that projects to exactly the shading rate in size), and bases its derivative values on that. The result is continuous derivative functions, regardless of the actual dicing rate.


What do smooth derivatives mean to me?

Since smooth derivatives are turned on by default, they should nearly always be transparent to the user. With few exceptions, the new method produces filtering that is more continuous and with fewer artifacts. Occasionally, though, when the dicer has made micropolygons slightly larger than the shading rate, the smooth derivatives will underfilter, which may result in aliasing.

If you suspect underfiltering may be causing aliasing on a given object, smooth derivatives can be deactivated on a per-shader basis. The shader compiler has two new command-line parameters that turn on and off the use of smooth derivatives:

shader -sd <shadername>
Turns smooth derivates on (default).
shader -nosd <shadername>
Turns smooth derivates off.

When smooth derivates are turned on, the global variables du and dv represent the smooth differentials, and when smooth derivatives are turned off, du and dv represent the old-style, grid-based differentials. Regardless of the compilation mode, you can access the two styles of derivatives explicitly with the following four global variables:

  • __gdu, __gdv - original, grid-based differentials
  • __sdu, __sdv - smooth, projection-based differentials

Shaders that are sensitive to different derivative methods can pick-and-choose with these variables.

Finally, note that the internal filtering functions (texture(), shadow(), environment(), filterstep(), area()) use smooth derivatives automatically when -sd is specified. If the aforementioned aliasing problems affect your use of these builtin functions, simply turn off smooth derivatives with --nosd when compiling the shader.