/* Copyrighted Pixar 1989 */ /* From the RenderMan Companion p.364 */ /* Listing 16.23 Displacement shader for bevelling perpendicular bilinear patches*/ /* * round(): displace the edge of a bilinear patch so that, if it is placed * next to another patch at a right angle, the edge will be rounded. */ displacement round (float radius = .10 ) { float uu, /* distance in u to the nearest "vertical" edge */ vv, /* distance in v to the nearest "horizontal" edge */ lu, /* "real" distance to the nearest "vertical" edge */ lv; /* "real" distance to the nearest "horizontal" edge */ point center,/* point toward which the surface is displaced */ dpdu, /* dPdu pointed toward patch center line */ dpdv; /* dPdv pointed toward patch center line */ /* Find the distance in parameter space from the nearest edge in u and in v, and the directions away from those edges. */ if (u < .5) { uu = u; dpdu = dPdu; } else { uu = 1 - u; dpdu = -dPdu; } if (v < .5) { vv = v; dpdv = dPdv; } else { vv = 1 - v; dpdv = -dPdv; } /* Find the distances from the edges in the current space. */ lu = length(dPdu*uu); lv = length(dPdv*vv); if (lu < radius || lv < radius) { /* only if within radius of an edge... */ /* * Find the point towards which the surface point will be * moved. This center is on the center line of a cylinder, if we * are not near the corner of the patch, or is the center of a * sphere, if we are. We move `center' to the nearest inflection * edge along u and/or v. */ center = point(0,0,0); if (lu < radius) center = (radius-lu) * normalize(dpdu); if (lv < radius) center += (radius-lv) * normalize(dpdv); /* Move center perpendicular to the surface */ center += P - radius*normalize(N); /* Make P be distance 'radius' along the line * from 'center' to P */ P = center + radius*normalize( P-center ); } N = calculatenormal(P); }