/* *----- fjs_fisheyelens.sl * * Description: * A near clip-plane shader that uses raytracing to provide * a simple fisheye lens for the camera. * * Usage: * User must define a square polygon just beyond the * near clip-plane distance. Generally, this polygon * fills the entire viewing frustrum. * * This shader is applied to the polygon and the user * should specify the polygon placement and the maximum * angle of the lens. * * The result is a lensed image on the square polygon. * The angular distribution is like polar graph paper, * with angle increasing linearly with distance from the * center and hitting one half of the specified lens angle * at the edge along the axes. Note that the maximum lens * angle will be larger along the diagonals. Any point on * the square polygon where the trace angle exceeds 90 * degrees is rendered black. In the limit of a 180 * degree fisheye, the result is a circular image with * black corners. * * Corners of polygon are assumed to be (in camera space): * [ scale, scale, zdistance] * [-scale, scale, zdistance] * [-scale, -scale, zdistance] * [ scale, -scale, zdistance] * * RIB example: * Clipping 0.099 1000.0 * Attribute "render" "integer visibility" [2] ### BMRT (value must be 2/3/6/7; default = 7) * Attribute "visibility" "integer reflection" [1] ### Entropy (default = 0) * Attribute "visibility" "int trace" [1] ### PRman (default = 0) * Declare "lens_angle" "uniform float" * Declare "zdistance" "uniform float" * Declare "scale" "uniform float" * Surface "fjs_fisheyelens" "lens_angle" [180] "zdistance" [0.1] "scale" [0.1] * Polygon "P" [0.1 0.1 0.1 -0.1 0.1 0.1 -0.1 -0.1 0.1 0.1 -0.1 0.1] * * History: * 2/24/05 - 1.2 - Fixed error, called radians() function before 90 degree check * * 4/ 5/04 - 1.1 - Fixed error in documentation, removed circular * lens restriction, noted BMRT / Entropy / PRman differences * * 12/17/01 - 1.0 - Cleaned up and documented - Frank Summers, * summers@stsci.edu * */ surface fjs_fisheyelens (float lens_angle = 180.0; float zdistance = 0.1; float scale = 0.1) { /* Do not shade near clip-plane polygon more than once * * The code below will begin the fisheye raytrace from the * camera. The near clip-plane polygon may then be hit a * second time by those rays. Checking the ray depth ensures * that only rays originally from the camera will be shaded. */ uniform float ray_depth = 0; /* BMRT / Entropy / PRman difference * * BMRT & Entropy code * * ray_depth = raylevel(); * * PRman code * * uniform float return_value = 0; * return_value = rayinfo("depth", ray_depth); * */ uniform float return_value = 0; return_value = rayinfo("depth", ray_depth); if (ray_depth > 0) { Oi = 0.0; Ci = color(0,0,0); /* Otherwise, shade with fisheyelens */ } else { /* Transform the point being shaded into camera coordinates */ varying point Pcam = transform("camera", P); /* Generate coordinates relative to the center of the polygon */ varying float ss = 0.5*xcomp(Pcam)/scale; varying float tt = 0.5*ycomp(Pcam)/scale; /* Calculate distance from center of the polygon */ varying float r = sqrt(ss*ss + tt*tt); /* Trace angle increases linearly with distance from center */ varying float polar_angle = lens_angle*r; /* If trace angle is greater than 90 degrees, paint it opaque and black */ if (polar_angle > 90.0) { Oi = 1.0; Ci = color(0,0,0); /* Otherwise, calculate ray to trace */ } else { /* Direction is calculated from angle and shade point coordinates */ polar_angle = radians(polar_angle); varying float z = cos(polar_angle); varying float x = 0.0; varying float y = 0.0; if (r > 0.0) { x = sin(polar_angle)*ss/r; y = sin(polar_angle)*tt/r; } /* Set trace direction and start point (at camera) */ varying vector tracedir = vector "camera" (x, y, z); varying point startpoint = point "camera" (0, 0, 0); /* Call trace function to perform the raytrace */ Oi = 1.0; Ci = trace(startpoint, tracedir); } } }