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 trace from the camera. The near clip-plane polygon will
* then be hit a second time by those rays. Checking raylevel ensures that only rays orginally from
* the camera will be shaded.
*/
float d;
rayinfo("depth",d);
if (d> 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);
/* if point is outside of polygon filling circle,paint it opaque and black */
if (r > 0.5) {
Oi = 1.0;
Ci = color(0,0,0);
/* otherwise, calculate ray to trace */
} else {
/* angle increases linearly with distance from center */
// r = pow(r,.3);
varying float polar_angle = radians(lens_angle)*r;
/* direction is calculated from angle and shade point coordinates */
varying float z = cos(polar_angle);
varying float x = sin(polar_angle)*ss/r;
varying float 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);
}
}
}