Re: Arbitrary derivatives
Larry Gritz <l...@...>
On Jan 19, 2010, at 12:52 AM, Bo Schwarzstein wrote:
Let's separate the language specification, from the implementation in this library, from what a renderer is expected to do when using the OSL library.
The language spec just requires that an implementation can take derivatives of any quantity with respect to "x" and "y". The definitions of x,y are purposely undefined, they are allowed to be anything convenient to the renderer as long as they are roughly perpendicular and that x and/or y change by approximately 1 from pixel to pixel (so derivatives can be used to estimate filter sizes). Also, the language itself doesn't really care how Dx() and Dy() are implemented.
In the implementation of the OSL runtime library, we really wanted derivatives to work just as well for ray tracers that shade in arbitrary locations than for Reyes-like renderers that have grids. We chose to use a kind of "automatic differentiation" based on dual arithmetic that tracks the differentials correctly for every calculation (read Dan Piponi's paper from JGT 2004 for a good introduction), so then the implementation of Dx() and Dy() is simply looking up the x and y partials of the variable in question. The bottom line is that it does not require grids or extra shading points.
At SPI, our renderer is a pure ray tracer, so for us x and y are pixel coordinates and we use ray differentials when setting up shading batches (you need to pass things like dP/dx and dP/dy into OSL, then it handles all the rest).
If a Reyes-like renderer (shading on grids) wanted to use our OSL implementation, there's no reason why a shading batch couldn't be arranged in a rectilinear grid, and if they wanted their derivatives to be aligned to the grids, they could still pass the initial values using x==u*du and y==v*dv and mimic what would usually happen for Reyes (even though our library would not actually be differencing grid points to find the derivatives).
Similarly, a pure GPU-based implementation of OSL would be allowed to have x,y aligned to screen space and use the funny/awful "alternating forward and backward differences" that GPUs do naturally.
Does that all make sense?
(Aside: at this moment, we use the dual arithmetic for everything, leading to quite a bit of wasted math. Among other optimizations I'm currently working on is to use the dual arithmetic only for the subset of calculations that lead to expressions whose derivatives are actually used, this should eliminate most of the extra math, since so few derivatives are taken. I've done some experiments that indicate that we can save somewhere near 30% when this is done.)