//
//             N K F l a r e . I N C
//   ------------------------------------------
//
//      Lens Flare "plug-in" for POV-RAY 3.0
//
//    Copyright (C) 1997           Nathan Kopp
//
//    Version 4.0                 August, 1997
//
//   ------------------------------------------
//
//    Documentation for NKFlare is in the file
//    NKFlare.TXT.  NKFlare.TXT must accompany
//    NKFlare.INC in all distributions.
//
// NKFlare is a very flexible lens flare include file for POV-Ray 3.0.
//
// Adding lens flare to your POV scene is now a simple as adding the
// following few lines to your scene description file:
//
//  #declare cam_loc = <x,y,z>    // use the x, y, and z of your camera
//  #declare light_loc = <x,y,z>  // use the x, y, and z of the light
//                                // you wish to flare
//  #declare lookat = <x,y,z>     // the look_at vector of your camera
//  #declare sky_vect = <x,y,z>   // the sky vector of your camera
//  #include "35mm.flr"           // or whatever pre-defined flare you like
//  #include "NKFlare.inc"        // create the lens flare
//
//   ------------------------------------------

#declare no_lens_flare = false  // ** assume no problems

#ifndef (cam_loc)
  #warning "You need to specify a camera location (cam_loc) for lens flare.\n"
  #declare no_lens_flare = true
#end

#ifndef (light_loc)
  #warning "You need to specify a light location (light_loc) for lens flare.\n"
  #declare no_lens_flare = true
#end

#ifndef (lookat)
  #warning "You need to specify a look_at location (lookat) for lens flare.\n"
  #declare no_lens_flare = true
#end

// *****************************************************************
// ** for older files that had '#declare moray = yes'
// ** instead of '#declare CoordSys = "moray"'
//
// ** Note: CoordSys only effects default sky_vect
// *****************************************************************
#ifdef(moray) #if(moray) #declare CoordSys = "moray" #end #end
#ifndef (CoordSys) #declare CoordSys = "pov" #end
#declare CoordSys = strlwr(CoordSys)      // CoordSys is case insensitive

#ifndef (sky_vect)
  #if (CoordSys = 'moray')
    #declare sky_vect = <0,0,1>
  #else
    #declare sky_vect = <0,1,0>
  #end
#end


#if (no_lens_flare = false)

// *****************************************************************
// ******** ALL'S OK.... CONTINUE WITH LENS FLARE ******************
// *****************************************************************

// if they defined "flare_type" and it is not blank, then
// use it for the include filename
//
#ifdef (flare_type)
  #if (strlen(flare_type)>0)
    #if (strcmp(flare_type, "camcorder")=0)
      #include "camcordr.flr"
    #else #if (strcmp(flare_type, "smallstar")=0)
      #include "smlstar.flr"
    #else #if (strcmp(flare_type, "warpflare")=0)
      #include "warp.flr"
    #else
      #declare filename = concat(flare_type,".flr")
      #if (file_exists(filename))
        #include filename
      #else
        #debug concat("Could not find the file: ",filename)
        #debug "\n"
      #end
    #end #end #end
  #end
#end

// *****************************************************************
// ** set flare_amount and flare_brightness if the user specifies
// ** a bright background
//
#ifdef (bright_background)
  #if (bright_background)
    #ifndef (flare_amount)     #declare flare_amount     = 0.4 #end
    #ifndef (flare_brightness) #declare flare_brightness = 1.5 #end
  #end
#end

// *****************************************************************
// ** Additional rotation degrees.
//
#ifndef (flare_rotate) #declare flare_rotate = 0 #end
#ifndef (flare_auto_rotate) #declare flare_auto_rotate = false #end
#ifndef (spots_auto_rotate) #declare spots_auto_rotate = false #end

// *****************************************************************
// ** sizes for primary flare
//
#ifndef (source_size) #declare source_size = .02 #end
#ifndef (glow_size)   #declare glow_size   = .15 #end
#ifndef (ring_size)   #declare ring_size   = .3 #end
#ifndef (ring_width)  #declare ring_width  = .1 #end

// *****************************************************************
// ** colors for primary flare
//
#ifndef (source_color)  #declare source_color  = <1, 1, 1> #end
#ifndef (glow_color)    #declare glow_color    = <1, 1, .7> #end
#ifndef (ring_color)    #declare ring_color    = <1, .7, .7> #end
#ifndef (source_bright) #declare source_bright = 2 #end
#ifndef (glow_bright)   #declare glow_bright   = 1.2 #end

// *****************************************************************
// ** translucencies for primary flare
//
#ifndef (source_tr)   #declare source_tr   = .1 #end
#ifndef (glow_tr)     #declare glow_tr     = .7 #end
#ifndef (ring_tr)     #declare ring_tr     = .8 #end
#ifndef (source_fade) #declare source_fade = .20 #end

// *****************************************************************
// ** attributes for big_glow
//
#ifndef (big_glow_size)  #declare big_glow_size  = 0 #end
#ifndef (big_glow_color) #declare big_glow_color = <1,1,1> #end
#ifndef (big_glow_tr)    #declare big_glow_tr    = 1 #end

// *****************************************************************
// ** attributes for streaks
//
#ifndef (streak_a_size) #declare streak_a_size = 0 #end
#ifndef (streak_b_size) #declare streak_b_size = 0 #end
#ifndef (streak_a_tr)   #declare streak_a_tr   = 1 #end
#ifndef (streak_b_tr)   #declare streak_b_tr   = 1 #end

// *****************************************************************
// ** default scale factors
//
#ifndef (main_flare_scale) #declare main_flare_scale = <1,1,1> #end
#ifndef (big_glow_scale)   #declare big_glow_scale = <1,1,1> #end

// *****************************************************************
// ** attributes for star (sparkle)
//
#ifndef (star_color)  #declare star_color = <1,1,1> #end
#ifndef (star_tr)     #declare star_tr    = .9 #end
#ifndef (star_size)   #declare star_size  = .2 #end
#ifndef (star_size2)  #declare star_size2 = star_size / 2 #end
#ifndef (num_arms)    #declare num_arms   = 9 #end
#ifndef (num_arms2)   #declare num_arms2  = 9*2 #end
#ifndef (star_width)  #declare star_width = .1 #end
#ifndef (star_width2) #declare star_width2= .05 #end
#ifndef (star_rand)   #declare star_rand  = 0 #end
#ifndef (star_rand2)  #declare star_rand2 = 0 #end
#ifndef (star_seed) #declare star_seed = seed(55) #end

#ifndef (star_mirror) #declare star_mirror = true #end
#ifndef (star_spread) #declare star_spread = true #end
#ifndef (crisp_star)  #declare crisp_star  = false #end
#ifndef (star_color_rand) #declare star_color_rand = 0 #end
#ifndef (star_size_rand) #declare star_size_rand = 0 #end

// *****************************************************************
// ** attributes for spots
//
#ifndef (num_spots)      #declare num_spots     = 4 #end
#ifndef (opposite_spots) #declare opposite_spots= 4 #end
#ifndef (skip_spots)     #declare skip_spots    = 1 #end
#ifndef (spot_dist)      #declare spot_dist     = .2 #end
#ifndef (spot_dist_pwr)  #declare spot_dist_pwr = 2 #end
#ifndef (percent_dots)   #declare percent_dots    = 0 #end
#ifndef (percent_hex)    #declare percent_hex     = 0 #end
#ifndef (percent_pent)   #declare percent_pent    = 0 #end

#ifndef (spot_size)     #declare spot_size     = .1 #end
#ifndef (spot_color)    #declare spot_color    = <1,1,.7> #end
#ifndef (spot_tr)       #declare spot_tr       = .9 #end

#ifndef (dot_size)      #declare dot_size      = .04 #end
#ifndef (dot_color)     #declare dot_color     = <.4,1,.5> #end
#ifndef (dot_tr)        #declare dot_tr        = .75 #end

// *****************************************************************
// ** randomness for spots
//
#ifndef (spot_seed)       #declare spot_seed       = seed(546) #end
#ifndef (spot_dist_rand)  #declare spot_dist_rand  = 0 #end

#ifndef (spot_size_rand)  #declare spot_size_rand  = 1 #end
#ifndef (spot_color_rand) #declare spot_color_rand = 0 #end
#ifndef (dot_size_rand)   #declare dot_size_rand   = 1 #end
#ifndef (dot_color_rand)  #declare dot_color_rand  = 0 #end
#ifndef (spot_fade_amount)#declare spot_fade_amount= 0 #end

// *****************************************************************
// ** Don't show flare source if they don't want us to
// *****************************************************************
#ifdef (show_flare_source) #if (show_flare_source = no)
   #declare source_tr = glow_tr
#end #end

// *****************************************************************
// ** this is the size of the sphere that's around the camera
// *****************************************************************
#ifndef (disc_size)
  #ifdef (sphere_size)
    #declare disc_size = sphere_size
  #else
    #declare disc_size = .001
  #end
#end

// *****************************************************************
// ** this is the scaling factor of the entire scene
// *****************************************************************
#ifndef (flare_size)
  #ifdef (flare_scale_factor)
    #declare flare_size = flare_scale_factor
  #else
    #declare flare_size = 1
  #end
#end
#ifndef (AmbientLight) #declare AmbientLight = <1,1,1> #end

// *****************************************************************
// ************ DECLARE TRANSFORM VARIABLES ********************
// *****************************************************************

// *****************************************************************
// ** compute relative location of camera to light source
// ** compute relative location of camera to center
// *****************************************************************
#declare lf_2light = cam_loc - light_loc
#declare lf_2ctr = cam_loc - lookat

// Now project lf_2light onto lf_2ctr to find new lf_2ctr vector.  This gives us
// a vector from cam_loc to lf_2ctr that is perpendecular to the relative
// lookat vector.  The newctr vector is used in for multiple flare
// spot calculation.
#declare lf_newctr = lf_2ctr * vdot(lf_2light,lf_2ctr) / (vlength(lf_2ctr)*vlength(lf_2ctr))

// *****************************************************************
// ** This hides the flare if it goes behind a planet
// *****************************************************************
#ifdef (planet_rad) #ifdef (light_rad) #ifdef (planet_loc)
  #declare lf_2planet = cam_loc - planet_loc

  // *****************************************************************
  // ** Don't hide if light is in front of planet
  // *****************************************************************
  #if (vlength(lf_2light) > vlength(lf_2planet))

     #declare lf_2light_p = lf_2light * vdot(lf_2planet,lf_2light) / (pow(vlength(lf_2light),2))
     #declare light_rad = light_rad * vlength(lf_2light_p) / vlength(lf_2light)

     #declare lf_temp_vect = vnormalize(lf_2light_p) - vnormalize(lf_2light)
     // *****************************************************************
     // ** Careful -- don't hide if planet is on other side of camera
     // *****************************************************************
     #if ((lf_temp_vect.x = 0) & (lf_temp_vect.y = 0) & (lf_temp_vect.z = 0))

        #declare lf_h = vlength(lf_2light_p - lf_2planet)
        #if (lf_h > (planet_rad + light_rad))
          #declare lf_visible = 1
          #declare lf_transmit = 0
        #else #if ( lf_h+light_rad < planet_rad )
          #declare lf_visible = 0
          #declare lf_transmit = 1
        #else
          #declare lf_area = pi*pow(light_rad,2)

          #declare lf_x = ( pow(planet_rad,2) - pow(light_rad,2) + lf_h*lf_h ) / (2*lf_h)
          #declare lf_y = sqrt( pow(planet_rad,2) - lf_x*lf_x )
          #declare lf_theta = atan2(lf_y,lf_x)
          #declare lf_area1 = pow(planet_rad,2) * lf_theta - lf_x*lf_y

          #declare lf_x = lf_h - lf_x
          #declare lf_y = sqrt( pow(light_rad,2) - lf_x*lf_x )
          #declare lf_theta = atan2(lf_y,lf_x)
          #declare lf_area2 = lf_area * lf_theta/pi - lf_x*lf_y

          #declare lf_visible = (lf_area - (lf_area1+lf_area2)) / lf_area
          #declare lf_transmit = 1-lf_visible

          #declare lf_intersect = vnormalize(lf_2light_p-lf_2planet) * lf_h
          #declare lf_vradius = (lf_2light_p-lf_2planet) + vnormalize(lf_2light_p-lf_2planet) * light_rad
// the following line was causing problems, so it was removed until I can debug it.  :(
//          #declare lf_2light = lf_2planet + lf_intersect + (lf_vradius - lf_intersect) * pow(lf_transmit,2)
        #end #end

        #warning "\n"
        #warning "Percent of light visible is: "
        #warning str(lf_visible*100,5,0)
        #warning "\n"

        #ifdef(flare_shrink) #if (flare_shrink = true)
          #declare flare_size = flare_size * pow((1-lf_transmit/2),.5)
        #end #end

        #if (lf_transmit = 1) #declare no_lens_flare = true #end

        #declare star_tr = star_tr + (1-star_tr) * pow(lf_transmit,2)
        #declare glow_tr = glow_tr + (1-glow_tr) * pow(lf_transmit,2)
        #declare ring_tr = ring_tr + (1-ring_tr) * pow(lf_transmit,2)
        #declare source_tr = source_tr + (1-source_tr) * pow(lf_transmit,2)
        #declare spot_tr = spot_tr + (1-spot_tr) * pow(lf_transmit,2)
        #declare dot_tr = dot_tr + (1-dot_tr) * pow(lf_transmit,2)
        #declare big_glow_tr = big_glow_tr + (1-big_glow_tr) * pow(lf_transmit,2)
     #end
   #end
#end #end #end

// *****************************************************************
// ** This hides the flare if it below a plane
// *****************************************************************
#ifdef (plane_loc) #ifdef (plane_norm) #ifdef (light_rad)
  #declare lf_to_plane = cam_loc - plane_loc
  #declare lf_area = pi*light_rad*light_rad

  // *****************************************************************
  //  Plane equation:   a(x-x0) + b(y-y0) + c(z-z0) = 0
  //  To find if light is on same side of plane as camera
  // *****************************************************************
  #declare lf_hide_plane = vdot( (lf_2light-lf_to_plane), plane_norm)
  #declare lf_hide_plane = lf_hide_plane / abs(lf_hide_plane)

  #declare lf_hide_plane2 = vdot( lf_to_plane, plane_norm)
  #declare lf_hide_plane2 = lf_hide_plane2 / abs(lf_hide_plane2)
  #if (lf_hide_plane2 > 0) #declare plane_norm = - plane_norm #end  // put camera on proper
                                                                    // side of plane
  #declare lf_hide_plane = lf_hide_plane - lf_hide_plane2
    // *****************************************************************
    //  zero = opposite sides, not zero = same side

  #declare lf_b_vector = lf_2light - lf_to_plane
  #declare lf_d = abs( vdot(plane_norm, lf_b_vector) ) / vlength(plane_norm)

  // *****************************************************************
  // ** set up area percents and top area percents
  // *****************************************************************
  #if ((lf_d < light_rad) & (lf_d != 0))
    #declare lf_x = sqrt( light_rad*light_rad - lf_d*lf_d)
    #declare lf_theta = atan2(lf_x, lf_d)
    #declare lf_a_pie = light_rad*light_rad * lf_theta
    #declare lf_a_tri = lf_x * lf_d

    #if (lf_hide_plane = 0)  // ** other side
      #declare lf_area_per = (lf_a_pie - lf_a_tri) / lf_area
      #declare lf_top_area = pi * lf_x*lf_x / lf_area
    #else                    // ** same side
      #declare lf_area_per = (lf_area - lf_a_pie + lf_a_tri) / lf_area
      #declare lf_top_area = 1.00
    #end
  #else
    #if (lf_d = 0)
      #declare lf_area_per = .50
      #declare lf_top_area = 1.00
    #else  // d>r
      #if (lf_hide_plane = 0)  // ** other side
        #declare lf_area_per = 0.0
        #declare lf_top_area = 0.00
      #else                    // ** same side
        #declare lf_area_per = 1.0
        #declare lf_top_area = 1.00
      #end
    #end
  #end

  #declare lf_theta = degrees (acos(vdot(-plane_norm,lf_2light) / (vlength(-plane_norm)*vlength(lf_2light))))
  #declare lf_theta = min(lf_theta,90)
  #declare lf_theta_per = lf_theta / 90

  #declare lf_visible = lf_top_area + (lf_area_per - lf_top_area) * lf_theta_per

  #if (lf_hide_plane = 0)  // ** other side
    #declare lf_2light = lf_2light + ((light_rad - lf_d)/4 + lf_d )*vnormalize(plane_norm)
  #else                    // ** same side
    #declare lf_2light = lf_2light + ((light_rad - lf_d)/4 )*vnormalize(plane_norm)
  #end

  #warning "\n"
  #warning "Percent of light visible is: "
  #warning str(lf_visible*100,5,0)
  #warning "\n"

  #declare lf_transmit = 1 - lf_visible

  #ifdef(flare_shrink) #if (flare_shrink = true)
    #declare flare_size = flare_size * pow((1-lf_transmit/2),.5)
  #end #end

  #if (lf_transmit = 1) #declare no_lens_flare = true #end

  #declare star_tr = star_tr + (1-star_tr) * pow(lf_transmit,2)
  #declare glow_tr = glow_tr + (1-glow_tr) * pow(lf_transmit,2)
  #declare ring_tr = ring_tr + (1-ring_tr) * pow(lf_transmit,2)
  #declare source_tr = source_tr + (1-source_tr) * pow(lf_transmit,2)
  #declare spot_tr = spot_tr + (1-spot_tr) * pow(lf_transmit,2)
  #declare dot_tr = dot_tr + (1-dot_tr) * pow(lf_transmit,2)
  #declare big_glow_tr = big_glow_tr + (1-big_glow_tr) * pow(lf_transmit,2)

#end #end #end


#ifdef (flare_amount)
   #declare lf_transmit = 1 - flare_amount
   #if (lf_transmit = 1) #declare no_lens_flare = true #end

   #declare star_tr = star_tr + (1-star_tr) * pow(lf_transmit,1)
   #declare glow_tr = glow_tr + (1-glow_tr) * pow(lf_transmit,1)
   #declare ring_tr = ring_tr + (1-ring_tr) * pow(lf_transmit,1)
   #declare source_tr = source_tr + (1-source_tr) * pow(lf_transmit,1)
   #declare spot_tr = spot_tr + (1-spot_tr) * pow(lf_transmit,1)
   #declare dot_tr = dot_tr + (1-dot_tr) * pow(lf_transmit,1)
   #declare big_glow_tr = big_glow_tr + (1-big_glow_tr) * pow(lf_transmit,1)
#end

// *****************************************************************
// ** compute rotation values for x and z axes
// *****************************************************************
#declare lf_2ctr = -lf_2ctr    #declare lf_2light = -lf_2light

// ** project z onto lf_2ctr and subtract from z
#declare lf_newz = z - lf_2ctr * vdot(z,lf_2ctr) / pow(vlength(lf_2ctr),2)
#declare lf_newz = vnormalize(lf_newz)

#declare lf_point_up = sky_vect - lf_2ctr * vdot(sky_vect,lf_2ctr) / pow(vlength(lf_2ctr),2)
#declare lf_point_ctr = lf_2light - lf_2ctr * vdot(lf_2light,lf_2ctr) / pow(vlength(lf_2ctr),2)

// ** cross newz and lf_2ctr to get a vector perpendicular to both
#declare lf_perp = vcross(lf_2ctr,lf_newz)

// ************************************
// ** Compute rotate towards sky vector
// ** project sky_vect onto perp
#declare lf_cdir = lf_perp * vdot(lf_point_up,lf_perp) / pow(vlength(lf_perp),2)

#declare lf_rotate_up = z*degrees(acos(vdot(lf_point_up,lf_newz)/vlength(lf_point_up)))
#if (lf_cdir.x <= 0) #declare lf_rotate_up = -lf_rotate_up #end

// ************************************
// ** Compute rotate towards center
// ** project sky_vect onto perp
#declare lf_cdir = lf_perp * vdot(lf_point_ctr,lf_perp) / pow(vlength(lf_perp),2)

#declare lf_rotate_ctr = z*degrees(acos(vdot(lf_point_ctr,lf_newz)/vlength(lf_point_ctr)))
#if (lf_cdir.x <= 0) #declare lf_rotate_ctr = -lf_rotate_ctr #end

#declare lf_rotate_x = -x*degrees(acos(vdot(lf_2ctr,z)/vlength(lf_2ctr)))
#declare lf_rotate_z = -z*degrees(atan2(lf_2ctr.x,lf_2ctr.y))

#declare lf_2ctr = -lf_2ctr    #declare lf_2light = -lf_2light


// *****************************************************************
// ** randoms are relative to their respective variables
// *****************************************************************
#declare spot_dist_rand = spot_dist_rand * spot_dist
#declare spot_size_rand = spot_size_rand * spot_size
#declare dot_size_rand  = dot_size_rand * dot_size
#declare star_size_rand = star_size_rand * star_size

// *****************************************************************
// ** set up lf_StarTex and lf_StarTex2 for the two sparkle textures
// *****************************************************************

#declare lf_temp_tr = 1.0
#if (crisp_star = true) #declare lf_temp_tr = star_tr #end

#if (num_arms > 0)
#declare lf_StarTex = pigment {
  radial

  #if (star_mirror = true)
    frequency 2
    #declare lf_tmp_width = star_width / num_arms * 2
    #declare lf_ave_dist  = 1 / num_arms * 2
  #else
    frequency 1
    #declare lf_tmp_width = star_width / num_arms
    #declare lf_ave_dist  = 1 / num_arms
  #end
  
  #declare lf_loc = 0

  color_map{
    [0.0          color star_color transmit star_tr   ]
    [lf_tmp_width color star_color transmit lf_temp_tr]
    [lf_tmp_width color star_color transmit 1.0       ]

    #declare lf_loc = lf_loc +  lf_ave_dist + (rand(star_seed)*2 - 1)*star_rand*(lf_ave_dist-2*lf_tmp_width)
    #while (lf_loc <(1-2*lf_tmp_width))
      #declare lf_s_color = star_color + star_color_rand * <(rand(star_seed) * 2 - 1),(rand(star_seed) * 2 - 1),(rand(spot_seed) * 2 - 1)>
      [lf_loc - lf_tmp_width  color lf_s_color transmit 1.0       ]
      [lf_loc - lf_tmp_width  color lf_s_color transmit lf_temp_tr]
      [lf_loc                 color lf_s_color transmit star_tr   ]
      [lf_loc + lf_tmp_width  color lf_s_color transmit lf_temp_tr]
      [lf_loc + lf_tmp_width  color lf_s_color transmit 1.0       ]
      #declare lf_loc = lf_loc +  lf_ave_dist + (rand(star_seed)*2 - 1)*star_rand*(lf_ave_dist-2*lf_tmp_width)
    #end

    [1-lf_tmp_width color star_color transmit 1.0       ]
    [1-lf_tmp_width color star_color transmit lf_temp_tr]
    [1.0            color star_color transmit star_tr   ]
  }

 rotate <90,0,-90>
}
#end

#if (num_arms2 > 0)
#declare lf_StarTex2 = pigment {
  radial
  #if (star_mirror = true)
    frequency 2
    #declare lf_tmp_width = star_width2 / num_arms2 * 2
    #declare lf_ave_dist  = 1 / num_arms2 * 2
  #else
    frequency 1
    #declare lf_tmp_width = star_width2 / num_arms2
    #declare lf_ave_dist  = 1 / num_arms2
  #end

  #declare lf_loc = 0

  color_map{
    [0.0          color star_color transmit star_tr ]
    [lf_tmp_width color star_color transmit 1.0     ]

    #declare lf_loc = lf_loc +  lf_ave_dist + (rand(star_seed)*2 - 1)*star_rand2*(lf_ave_dist-2*lf_tmp_width)
    #while (lf_loc <(1-2*lf_tmp_width))
      #declare lf_s_color = star_color + star_color_rand * <(rand(star_seed) * 2 - 1),(rand(star_seed) * 2 - 1),(rand(spot_seed) * 2 - 1)>
      [lf_loc - lf_tmp_width  color lf_s_color transmit 1.0    ]
      [lf_loc                 color lf_s_color transmit star_tr]
      [lf_loc + lf_tmp_width  color lf_s_color transmit 1.0    ]
      #declare lf_loc = lf_loc +  lf_ave_dist + (rand(star_seed)*2 - 1)*star_rand2*(lf_ave_dist-2*lf_tmp_width)
    #end

    [1-lf_tmp_width color star_color transmit 1.0     ]
    [1.0            color star_color transmit star_tr ]
  }

 rotate <90,0,-90>
}
#end

#declare lf_PrimaryFlare = pigment {
  wood
  color_map {
     [ 0.0             color source_color*source_bright transmit source_tr ]
     [ source_size     color source_color*glow_bright transmit source_tr   ]
     [ source_size + (glow_size - source_size)*source_fade
                       color glow_color*glow_bright
                       transmit (source_tr+glow_tr)/2 ]

     [ glow_size                 color glow_color   transmit glow_tr ]
     [ (glow_size + ring_size)/2 color glow_color   transmit 1       ]

     [ (glow_size + ring_size)/2 color ring_color   transmit 1            ]
     [ (ring_size - ring_width * ring_size) color ring_color   transmit 1 ]
     [ ring_size                 color ring_color   transmit ring_tr      ]
     [ (ring_size + ring_width * ring_size) color ring_color   transmit 1 ]
     [ 1 color rgbt <0,0,0,1> ]
  } #ifdef (flare_scallop_wave) #if (flare_scallop_wave = yes) scallop_wave #end #end
}

#declare lf_Finish = finish {
  refraction off
  specular 0
  phong 0
  diffuse 0.0
  reflection 0.0

  #declare lf_bright = <1,1,1>
  #ifdef (AmbientLight)
    #declare lf_bright = lf_bright / AmbientLight
  #end
  #ifdef (flare_brightness)
    #declare lf_bright = lf_bright * flare_brightness
  #end

  ambient lf_bright
}

// *****************************************************************
// ** First, make sure the camera is in front of the camera by
//    checking the plane with normal from cam_loc to lookat.
//
//  Plane equation:   a(x-x0) + b(y-y0) + c(z-z0) = 0
//
// *****************************************************************
#ifdef(lookat)
  #declare cam_plane = 1 * vdot(lf_2ctr, lf_2light)
#else
  #declare cam_plane = 1  // assume flare in front of camera if no lookat given
#end

#ifndef (lf_visible) #declare lf_visible = 1 #end
#if ((cam_plane < 0) | (no_lens_flare = true))
  #warning "Light is behind camera or behind the planet.  Lens flare not created."
  // *****************************************************************
  // Skip lens flare completely... can have an impact on
  // render speed.
  // *****************************************************************
#else

// *****************************************************************
// ********** THE ACTUAL DISCS FOR LENS FLARE **********************
// *****************************************************************

#ifndef (lf_flares_drawn) #declare lf_flares_drawn = 0 #end

#declare lf_new_disc_size = disc_size + .001 * lf_flares_drawn
disc {
  #declare lf_bound_y = (ring_size*(1+ring_width))/2
  <0,0,0>, z, lf_bound_y

  texture {
    // ***************** Primary flare ********************
    pigment {
      lf_PrimaryFlare
    }
    finish { lf_Finish }
  }
  scale main_flare_scale * lf_new_disc_size * flare_size

  #if (flare_auto_rotate = false)
    rotate lf_rotate_up
  #else
    rotate lf_rotate_ctr
  #end
  rotate flare_rotate*z
  rotate lf_rotate_x
  rotate lf_rotate_z

  #declare lf_dist = 1/( vdot(lf_2light,lf_2ctr)/(vlength(lf_2ctr)*vlength(lf_2light)) )
  translate cam_loc + lf_new_disc_size * vnormalize(-lf_2light)*lf_dist
  no_shadow hollow
}
#declare lf_flares_drawn = lf_flares_drawn + 1

#if ((num_arms > 0) | (num_arms2 > 0))

#if (star_spread)
#declare lf_new_disc_size = disc_size + .001 * lf_flares_drawn
disc {
  #declare lf_bound_y = max(star_size*3,star_size2*3)/2
  <0,0,0>, z, lf_bound_y
  #if (num_arms > 0)
    texture {
      // ************** Star-type flare *********************
      pigment {
        wood
        pigment_map {
          [ 0.0            lf_StarTex]
          [ star_size      lf_StarTex]
          [ star_size * 3  lf_StarTex transmit 1]
          [ 1              lf_StarTex transmit 1]
        }
      }
      finish { lf_Finish }
    }
  #end
  #if (num_arms2 > 0)
    texture {
      // ************** Star-type2 flare *********************
      pigment {
        wood
        pigment_map {
          [ 0.0             lf_StarTex2]
          [ star_size2      lf_StarTex2]
          [ star_size2 * 3  lf_StarTex2 transmit 1 ]
          [ 1               lf_StarTex2 transmit 1 ]
        }
      }
      finish { lf_Finish }
    }
  #end

  scale main_flare_scale * lf_new_disc_size * flare_size

  #if (flare_auto_rotate = false)
    rotate lf_rotate_up
  #else
    rotate lf_rotate_ctr
  #end
  rotate flare_rotate*z
  rotate lf_rotate_x
  rotate lf_rotate_z

  #declare lf_dist = 1/( vdot(lf_2light,lf_2ctr)/(vlength(lf_2ctr)*vlength(lf_2light)) )
  translate cam_loc + lf_new_disc_size * vnormalize(-lf_2light)*lf_dist
  no_shadow hollow
}
#declare lf_flares_drawn = lf_flares_drawn + 1

#else // star_spread
  // **************************************
  // Create a bunch of streaks to simulate
  // the sparkle pattern
  //
#declare lf_tmp_num=2
#while (lf_tmp_num>0)

  #if (lf_tmp_num = 2)
  #if (star_mirror)
    #declare lf_num = num_arms / 2
    #declare lf_tmp_width = star_width / num_arms * .25
    #declare lf_ave_ang  = 360 / num_arms // 2
  #else
    #declare lf_num = num_arms
    #declare lf_tmp_width = star_width / num_arms * .25
    #declare lf_ave_ang  = 360 / num_arms
  #end
  #else
  #if (star_mirror)
    #declare lf_num = num_arms2 / 2
    #declare lf_tmp_width = star_width2 / num_arms2 * .25
    #declare lf_ave_ang  = 360 / num_arms2 // 2
  #else
    #declare lf_num = num_arms2
    #declare lf_tmp_width = star_width2 / num_arms2 * .25
    #declare lf_ave_ang  = 360 / num_arms2
  #end
  #end

  #while (lf_num > 0)

    #if (lf_tmp_num = 2)
    #declare lf_tmp_size = star_size + (rand(star_seed) * 2 - 1) * star_size_rand
    #declare lf_tmp_ang  = lf_num * lf_ave_ang + (rand(star_seed) * 2 - 1) * star_rand * lf_ave_ang
    #declare lf_s_color = star_color + star_color_rand * <(rand(star_seed) * 2 - 1),(rand(star_seed) * 2 - 1),(rand(spot_seed) * 2 - 1)>
    #else
    #declare lf_tmp_size = star_size2 + (rand(star_seed) * 2 - 1) * star_size_rand
    #declare lf_tmp_ang  = lf_num * lf_ave_ang + (rand(star_seed) * 2 - 1) * star_rand2 * lf_ave_ang
    #declare lf_s_color = star_color + star_color_rand * <(rand(star_seed) * 2 - 1),(rand(star_seed) * 2 - 1),(rand(spot_seed) * 2 - 1)>
    #end

    #declare lf_new_disc_size = disc_size + .001 * lf_flares_drawn
    disc {
      <0,0,0>, z, 1
      texture {
        pigment {
          wood
          ramp_wave
          color_map{
            [0.0 color lf_s_color transmit star_tr]
            #if (crisp_star=true)
              [1.0 color lf_s_color transmit star_tr]
            #else
              [1.0 color lf_s_color transmit 1.0]
            #end
          }
        }
        finish { lf_Finish }
      }
      
      scale <lf_tmp_size,lf_tmp_width,1> * lf_new_disc_size * flare_size
      #if (star_mirror=false)
        scale <.5,1,1>
        translate <.5,0,0>*lf_tmp_size* lf_new_disc_size.x * flare_size.x
      #end

      rotate (lf_tmp_ang + flare_rotate)*z

      scale main_flare_scale

      #if (flare_auto_rotate = false)
        rotate lf_rotate_up
      #else
        rotate lf_rotate_ctr
      #end
      rotate lf_rotate_x
      rotate lf_rotate_z

      #declare lf_dist = 1/( vdot(lf_2light,lf_2ctr)/(vlength(lf_2ctr)*vlength(lf_2light)) )
      translate cam_loc + lf_new_disc_size * vnormalize(-lf_2light)*lf_dist
      no_shadow hollow
    }
    #declare lf_flares_drawn = lf_flares_drawn + 1
    #declare lf_num = lf_num - 1
  #end
#declare lf_tmp_num = lf_tmp_num-1
#end //while

#end // star_spread


#end

// ************** streak_a flare *********************
#declare lf_new_disc_size = disc_size + .001 * lf_flares_drawn
#if ((streak_a_size > 0) & (streak_a_tr < 1))
  disc {
    <0,0,0>, z, .5
    texture {
      pigment {
        wood
        color_map {
           [ 0.0  color streak_a_center_color transmit streak_a_tr ]
           [ 1.0  color streak_a_color transmit 1           ]
        }
      }
      finish { lf_Finish }
    }
    scale streak_a_scale * streak_a_size * lf_new_disc_size * flare_size

    #if (streak_a_auto_rotate = false)
      rotate lf_rotate_up
    #else
      rotate lf_rotate_ctr
    #end
    rotate streak_a_rotate*z
    rotate lf_rotate_x
    rotate lf_rotate_z

    #declare lf_dist = 1/( vdot(lf_2light,lf_2ctr)/(vlength(lf_2ctr)*vlength(lf_2light)) )
    translate cam_loc + lf_new_disc_size * vnormalize(-lf_2light)*lf_dist
    no_shadow hollow
  }
  #declare lf_flares_drawn = lf_flares_drawn + 1
#end

// ************** streak_b flare *********************
#declare lf_new_disc_size = disc_size + .001 * lf_flares_drawn
#if ((streak_b_size > 0) & (streak_b_tr < 1))
  disc {
    <0,0,0>, z, .5
    texture {
      pigment {
        wood
        color_map {
           [ 0.0  color streak_b_center_color transmit streak_b_tr ]
           [ 1.0  color streak_b_color transmit 1           ]
        }
      }
      finish { lf_Finish }
    }
    scale streak_b_scale * streak_b_size * lf_new_disc_size * flare_size

    #if (streak_b_auto_rotate = false)
      rotate lf_rotate_up
    #else
      rotate lf_rotate_ctr
    #end
    rotate streak_b_rotate*z
    rotate lf_rotate_x
    rotate lf_rotate_z

    #declare lf_dist = 1/( vdot(lf_2light,lf_2ctr)/(vlength(lf_2ctr)*vlength(lf_2light)) )
    translate cam_loc + lf_new_disc_size * vnormalize(-lf_2light)*lf_dist
    no_shadow hollow
  }
  #declare lf_flares_drawn = lf_flares_drawn + 1
#end

// ************** big_glow flare *********************
#declare lf_new_disc_size = disc_size + .001 * lf_flares_drawn
#if ((big_glow_size > 0) & (big_glow_tr < 1))
  disc {
    #declare lf_bound_y = big_glow_size/2
    <0,0,0>, z, lf_bound_y
    texture {
      pigment {
        wood
        color_map {
           [ 0.0           color big_glow_color transmit big_glow_tr ]
           [ big_glow_size color big_glow_color transmit 1           ]
           [ 1 color       rgbt <0,0,0,1> ]
        }
      }
      finish { lf_Finish }
    }
    scale big_glow_scale * lf_new_disc_size * flare_size

    #if (flare_auto_rotate = false)
      rotate lf_rotate_up
    #else
      rotate lf_rotate_ctr
    #end
    rotate lf_rotate_x
    rotate lf_rotate_z

    #declare lf_dist = 1/( vdot(lf_2light,lf_2ctr)/(vlength(lf_2ctr)*vlength(lf_2light)) )
    translate cam_loc + lf_new_disc_size * vnormalize(-lf_2light)*lf_dist
    no_shadow hollow
  }
  #declare lf_flares_drawn = lf_flares_drawn + 1
#end

//  *********************************************************************
//  *********************  Multiple lens flare spots ********************
//  *********************************************************************
#declare num_spots = num_spots + skip_spots
#declare opposite_spots = opposite_spots + skip_spots

#while (num_spots > skip_spots)
  // *****************************************************************
  // ** randomly shift various attributes
  // *****************************************************************
  #declare lf_s_size  = spot_size + (rand(spot_seed) * 2 - 1) * spot_size_rand
  #declare lf_s_dist  = (rand(spot_seed) * 2 - 1) * spot_dist_rand
  #declare lf_s_color = spot_color + spot_color_rand * <(rand(spot_seed) * 2 - 1),(rand(spot_seed) * 2 - 1),(rand(spot_seed) * 2 - 1)>
  #declare lf_d_size  = dot_size + (rand(spot_seed) * 2 - 1) * dot_size_rand
  #declare lf_d_color = dot_color + dot_color_rand * <(rand(spot_seed) * 2 - 1),(rand(spot_seed) * 2 - 1),(rand(spot_seed) * 2 - 1)>

  #declare lf_pentagon = false
  
  #declare lf_is_dot = rand(spot_seed)

  #switch (lf_is_dot)
  #range (0,percent_dots)
    #declare lf_SpotPigment = pigment {
      wood
      #declare tmp_tr = dot_tr + (1-dot_tr)*spot_fade_amount*(num_spots - skip_spots)
      color_map {
         [ 0.0                        color lf_d_color transmit tmp_tr         ]
         [ lf_d_size / 1.2            color lf_d_color transmit (1+tmp_tr)*.53 ]
         [ lf_d_size                  color lf_d_color transmit 1              ]
         [ 1 color rgbt <0,0,0,1> ]
      }
    }
    #declare lf_bound_y = lf_d_size/2
  #break

  #range (percent_dots,percent_dots+percent_hex)
    #declare tmp_tr = spot_tr + (1-spot_tr)*spot_fade_amount*(num_spots - skip_spots)
    #declare lf_SpotPigment = pigment{hexagon lf_s_color transmit tmp_tr,rgbt<1,1,1,1>,rgbt<1,1,1,1> rotate 90*x scale .5*lf_s_size}
    #declare lf_bound_y = lf_s_size/2
  #break

  #range (percent_dots+percent_hex,percent_dots+percent_hex+percent_pent)
    #declare lf_pentagon = true
    #declare tmp_tr = spot_tr + (1-spot_tr)*spot_fade_amount*(num_spots - skip_spots)
    #declare lf_SpotPigment = pigment{color lf_s_color transmit tmp_tr}
    #declare lf_bound_y = lf_s_size/2
  #break

  #else
    #declare lf_SpotPigment = pigment {
      wood
      #declare tmp_tr = spot_tr + (1-spot_tr)*spot_fade_amount*(num_spots - skip_spots)
      color_map {
         [ 0.0                       color lf_s_color transmit 1              ]
         [ lf_s_size / 1.8           color lf_s_color transmit (1+tmp_tr)*.53 ]
         [ lf_s_size                 color lf_s_color transmit tmp_tr         ]
         [ lf_s_size +.1 * lf_s_size color lf_s_color transmit 1              ]
         [ 1 color rgbt <0,0,0,1> ]
      }
    }
    #declare lf_bound_y = lf_s_size*1.1/2
  #end

  // ************* Arm pointing toward middle ************
  // *****************************************************
  #declare lf_new_disc_size = disc_size + .001 * lf_flares_drawn

  #if (lf_pentagon=false)
  disc {
    <0,0,0>, z, lf_bound_y
  #else
  polygon {
    6,
    <0,-1>
    < cos(radians(18)),-sin(radians(18))>,
    < cos(radians(54)), sin(radians(54))>,
    <-cos(radians(54)), sin(radians(54))>,
    <-cos(radians(18)),-sin(radians(18))>,
    <0,-1>
    scale lf_s_size
  #end
    texture {
      pigment { lf_SpotPigment }
      finish { lf_Finish }
    }
    // *****************************************************************
    // ** calculate the apparant position of the flare spot
    // *****************************************************************
    #declare lf_2spot = lf_2light + (lf_newctr - lf_2light) * (spot_dist * pow(num_spots, spot_dist_pwr) + lf_s_dist)

    scale lf_new_disc_size * flare_size

    #if (spots_auto_rotate=true)
      rotate lf_rotate_ctr
    #else
      rotate lf_rotate_up
    #end
    rotate lf_rotate_x
    rotate lf_rotate_z

    #declare lf_dist = 1/( vdot(lf_2spot,lf_2ctr)/(vlength(lf_2ctr)*vlength(lf_2spot)) )
    translate cam_loc + lf_new_disc_size * vnormalize(-lf_2spot)*lf_dist
    no_shadow hollow
  }
  #declare lf_flares_drawn = lf_flares_drawn + 1

#if (num_spots <= opposite_spots) // !*!*!*!*!*!*!*!*!*!
  // *****************************************************************
  // ** randomly shift various attributes - again
  // *****************************************************************
  #declare lf_s_size  = spot_size + (rand(spot_seed) * 2 - 1) * spot_size_rand
  #declare lf_s_dist  = (rand(spot_seed) * 2 - 1) * spot_dist_rand
  #declare lf_s_color = spot_color + spot_color_rand * <(rand(spot_seed) * 2 - 1),(rand(spot_seed) * 2 - 1),(rand(spot_seed) * 2 - 1)>
  #declare lf_d_size  = dot_size + (rand(spot_seed) * 2 - 1) * dot_size_rand
  #declare lf_d_color = dot_color + dot_color_rand * <(rand(spot_seed) * 2 - 1),(rand(spot_seed) * 2 - 1),(rand(spot_seed) * 2 - 1)>

  #declare lf_pentagon = false
  
  #declare lf_is_dot = rand(spot_seed)

  #switch (lf_is_dot)
  #range (0,percent_dots)
    #declare lf_SpotPigment = pigment {
      wood
      #declare tmp_tr = dot_tr + (1-dot_tr)*spot_fade_amount*(num_spots - skip_spots)
      color_map {
         [ 0.0                        color lf_d_color transmit tmp_tr         ]
         [ lf_d_size / 1.2            color lf_d_color transmit (1+tmp_tr)*.53 ]
         [ lf_d_size                  color lf_d_color transmit 1              ]
         [ 1 color rgbt <0,0,0,1> ]
      }
    }
    #declare lf_bound_y = lf_d_size/2
  #break

  #range (percent_dots,percent_dots+percent_hex)
    #declare tmp_tr = spot_tr + (1-spot_tr)*spot_fade_amount*(num_spots - skip_spots)
    #declare lf_SpotPigment = pigment{hexagon lf_s_color transmit tmp_tr,rgbt<1,1,1,1>,rgbt<1,1,1,1> rotate 90*x scale .5*lf_s_size}
    #declare lf_bound_y = lf_s_size/2
  #break

  #range (percent_dots+percent_hex,percent_dots+percent_hex+percent_pent)
    #declare lf_pentagon = true
    #declare tmp_tr = spot_tr + (1-spot_tr)*spot_fade_amount*(num_spots - skip_spots)
    #declare lf_SpotPigment = pigment{color lf_s_color transmit tmp_tr}
    #declare lf_bound_y = lf_s_size/2
  #break

  #else
    #declare lf_SpotPigment = pigment {
      wood
      #declare tmp_tr = spot_tr + (1-spot_tr)*spot_fade_amount*(num_spots - skip_spots)
      color_map {
         [ 0.0                       color lf_s_color transmit 1              ]
         [ lf_s_size / 1.8           color lf_s_color transmit (1+tmp_tr)*.53 ]
         [ lf_s_size                 color lf_s_color transmit tmp_tr         ]
         [ lf_s_size +.1 * lf_s_size color lf_s_color transmit 1              ]
         [ 1 color rgbt <0,0,0,1> ]
      }
    }
    #declare lf_bound_y = lf_s_size*1.1/2
  #end

  // ************* Arm pointing away *********************
  // *****************************************************
  #declare lf_new_disc_size = disc_size + .001 * lf_flares_drawn

  #if (lf_pentagon=false)
  disc {
    <0,0,0>, z, lf_bound_y
  #else
  polygon {
    6,
    <0,-1>
    < cos(radians(18)),-sin(radians(18))>,
    < cos(radians(54)), sin(radians(54))>,
    <-cos(radians(54)), sin(radians(54))>,
    <-cos(radians(18)),-sin(radians(18))>,
    <0,-1>
    scale lf_s_size
  #end
    texture {
      pigment { lf_SpotPigment }
      finish { lf_Finish }
    }
    // *****************************************************************
    // ** calculate the apparant position of the flare spot
    // *****************************************************************
    #declare lf_2spot = lf_2light - (lf_newctr - lf_2light) * (spot_dist * pow(num_spots, spot_dist_pwr) + lf_s_dist)

    scale lf_new_disc_size * flare_size

    #if (spots_auto_rotate=true)
      rotate lf_rotate_ctr+180*z
    #else
      rotate lf_rotate_up
    #end
    rotate lf_rotate_x
    rotate lf_rotate_z

    #declare lf_dist = 1/( vdot(lf_2spot,lf_2ctr)/(vlength(lf_2ctr)*vlength(lf_2spot)) )
    translate cam_loc + lf_new_disc_size * vnormalize(-lf_2spot)*lf_dist
    no_shadow hollow
  }
  #declare lf_flares_drawn = lf_flares_drawn + 1

  #declare opposite_spots = opposite_spots - 1
#end

  #declare num_spots = num_spots - 1
#end

#ifdef (lf_50mm_spots)  #if (lf_50mm_spots = true)
  #declare lf_new_disc_size = disc_size + .001 * lf_flares_drawn
  disc {
    #declare lf_bound_y = ring_size*2.30/2
    <0,0,0>, z, lf_bound_y
    texture {
      // *****************************************************************
      // ***************** 50-300mm xtra large spot **********************
      // *****************************************************************
      pigment {
        wood
        color_map {
           [ 0.0              color transmit 1                ]
           [ ring_size*2      color <1,1,.7> transmit 1       ]
           [ ring_size*2.15   color <1,1,.7> transmit spot_tr ]
           [ ring_size*2.15   color <.8,.8,1> transmit spot_tr]
           [ ring_size*2.30   color <.8,.8,1> transmit 1      ]
           [ 1 color rgbt <0,0,0,1> ]
        }
      }
      finish { lf_Finish }
    }
    // *****************************************************************
    // ** calculate the apparant position of the flare spot
    // *****************************************************************
    #declare lf_2spot = lf_2light + (lf_newctr - lf_2light) * 2

    scale lf_new_disc_size * flare_size

    #if (flare_auto_rotate = false)
      rotate lf_rotate_up
    #else
      rotate lf_rotate_ctr
    #end
    rotate lf_rotate_x
    rotate lf_rotate_z

    #declare lf_dist = 1/( vdot(lf_2spot,lf_2ctr)/(vlength(lf_2ctr)*vlength(lf_2spot)) )
    translate cam_loc + lf_new_disc_size * vnormalize(-lf_2spot)*lf_dist
    no_shadow hollow
  }
  #declare lf_flares_drawn = lf_flares_drawn + 1
#end #end

#ifdef (lf_35mm_spots)  #if (lf_35mm_spots = true)
  #declare lf_new_disc_size = disc_size + .001 * lf_flares_drawn
  disc {
    #declare lf_bound_y = ring_size*2.15/2
    <0,0,0>, z, lf_bound_y
    texture {
      // *****************************************************************
      // ***************** 35mm xtra large spot **************************
      // *****************************************************************
      pigment {
        wood
        color_map {
           [ 0.0              color <.8,1,.8> transmit spot_tr*.95     ]
           [ ring_size/3      color <.8,1,.8> transmit spot_tr        ]
           [ ring_size*1.5    color <.8,1,.8> transmit (spot_tr+1)/2  ]
           [ ring_size*2      color <.8,1,.8> transmit spot_tr        ]
           [ ring_size*2.15   color <.8,1,.8> transmit 1              ]
           [ 1 color rgbt <0,0,0,1> ]
        }
      }
      finish { lf_Finish }
    }
    // *****************************************************************
    // ** calculate the apparant position of the flare spot
    // *****************************************************************
    #declare lf_2spot = lf_2light + (lf_newctr - lf_2light) * 2

    scale lf_new_disc_size * flare_size

    #if (flare_auto_rotate = false)
      rotate lf_rotate_up
    #else
      rotate lf_rotate_ctr
    #end
    rotate lf_rotate_x
    rotate lf_rotate_z

    #declare lf_dist = 1/( vdot(lf_2spot,lf_2ctr)/(vlength(lf_2ctr)*vlength(lf_2spot)) )
    translate cam_loc + lf_new_disc_size * vnormalize(-lf_2spot)*lf_dist
    no_shadow hollow
  }
  #declare lf_flares_drawn = lf_flares_drawn + 1
#end #end

#ifdef (lf_space_spots)  #if (lf_space_spots = true)
  #declare lf_new_disc_size = disc_size + .001 * lf_flares_drawn
  disc {
    #declare lf_bound_y = ring_size*2.30/2
    <0,0,0>, z, lf_bound_y
    texture {
      // *****************************************************************
      // ***************** anamorphic "shadow" 1    **********************
      // *****************************************************************
      pigment {
        wood
        color_map {
           [ 0.0              color transmit 1 ]
           [ ring_size        color ring_color transmit 1      ]
           [ ring_size*1.15   color ring_color transmit spot_tr*.98]
           [ ring_size*1.15   color ring_color transmit spot_tr*.98]
           [ ring_size*1.30   color ring_color transmit 1      ]
           [ 1 color rgbt <0,0,0,1> ]
        }
      }
      finish { lf_Finish }
    }
    // *****************************************************************
    // ** calculate the apparant position of the flare spot
    // *****************************************************************
    #declare lf_2spot = lf_2light + (lf_newctr - lf_2light) * 2

    scale main_flare_scale * lf_new_disc_size * flare_size

    #if (flare_auto_rotate = false)
      rotate lf_rotate_up
    #else
      rotate lf_rotate_ctr
    #end
    rotate lf_rotate_x
    rotate lf_rotate_z

    #declare lf_dist = 1/( vdot(lf_2spot,lf_2ctr)/(vlength(lf_2ctr)*vlength(lf_2spot)) )
    translate cam_loc + lf_new_disc_size * vnormalize(-lf_2spot)*lf_dist
    no_shadow hollow
  }
  #declare lf_flares_drawn = lf_flares_drawn + 1

  #declare lf_new_disc_size = disc_size + .001 * lf_flares_drawn
  disc {
    #declare lf_bound_y = ring_size*2.30/2
    <0,0,0>, z, lf_bound_y
    texture {
      // *****************************************************************
      // ***************** anamorphic "shadow" 2    **********************
      // *****************************************************************
      pigment {
        wood
        color_map {
           [ 0.0              color transmit 1 ]
           [ ring_size        color glow_color transmit 1      ]
           [ ring_size*1.15   color glow_color transmit spot_tr*.98]
           [ ring_size*1.15   color glow_color transmit spot_tr*.98]
           [ ring_size*1.30   color glow_color transmit 1      ]
           [ 1 color rgbt <0,0,0,1> ]
        }
      }
      finish { lf_Finish }
    }
    // *****************************************************************
    // ** calculate the apparant position of the flare spot
    // *****************************************************************
    #declare lf_2spot = lf_2light + (lf_newctr - lf_2light) * 2.02

    scale main_flare_scale*.8 * lf_new_disc_size * flare_size

    #if (flare_auto_rotate = false)
      rotate lf_rotate_up
    #else
      rotate lf_rotate_ctr
    #end
    rotate lf_rotate_x
    rotate lf_rotate_z

    #declare lf_dist = 1/( vdot(lf_2spot,lf_2ctr)/(vlength(lf_2ctr)*vlength(lf_2spot)) )
    translate cam_loc + lf_new_disc_size * vnormalize(-lf_2spot)*lf_dist
    no_shadow hollow
  }
  #declare lf_flares_drawn = lf_flares_drawn + 1

  #declare lf_new_disc_size = disc_size + .001 * lf_flares_drawn
  disc {
    <0,0,0>, z, .5
    texture {
      // *****************************************************************
      // ***************** anamorphic "shadow" 3    **********************
      // *****************************************************************
      pigment {
        wood
        color_map {
           [ 0.0           color streak_a_color transmit spot_tr*.9 ]
           [ 1.0  color streak_a_color transmit 1          ]
        }
      }
      finish { lf_Finish }
    }
    // *****************************************************************
    // ** calculate the apparant position of the flare spot
    // *****************************************************************
    #declare lf_2spot = lf_2light + (lf_newctr - lf_2light) * 1.8

    scale streak_a_scale*<.2,1,1>* streak_a_size * lf_new_disc_size * flare_size

    #if (streak_a_auto_rotate = false)
      rotate lf_rotate_up
    #else
      rotate lf_rotate_ctr
    #end
    rotate streak_a_rotate*z
    rotate lf_rotate_x
    rotate lf_rotate_z

    #declare lf_dist = 1/( vdot(lf_2spot,lf_2ctr)/(vlength(lf_2ctr)*vlength(lf_2spot)) )
    translate cam_loc + lf_new_disc_size * vnormalize(-lf_2spot)*lf_dist
    no_shadow hollow
  }
#end #end

#ifdef (lf_camcorder_spots)  #if (lf_camcorder_spots = true)
  #declare lf_new_disc_size = disc_size + .001 * lf_flares_drawn
  disc {
    #declare lf_bound_y = ring_size*1.15*1.5/2
    <0,0,0>, z, lf_bound_y
    texture {
      // *****************************************************************
      // ***************** camcorder xtra large spot *********************
      // *****************************************************************
      pigment {
        wood
        color_map {
           [ 0.0              color <.5,1,.9> transmit spot_tr]
           [ ring_size*0.90*1.5   color <.5,1,.9> transmit .95         ]
           [ ring_size*1.15*1.6   color <0,0,0> transmit 1          ]
           [ 1 color rgbt <0,0,0,1> ]
        }
      }
      finish { lf_Finish }
    }
    // *****************************************************************
    // ** calculate the apparant position of the flare spot
    // *****************************************************************
    #declare lf_2spot = lf_2light + (lf_newctr - lf_2light) * 2

    scale lf_new_disc_size * flare_size

    #if (flare_auto_rotate = false)
      rotate lf_rotate_up
    #else
      rotate lf_rotate_ctr
    #end
    rotate lf_rotate_x
    rotate lf_rotate_z

    #declare lf_dist = 1/( vdot(lf_2spot,lf_2ctr)/(vlength(lf_2ctr)*vlength(lf_2spot)) )
    translate cam_loc + lf_new_disc_size * vnormalize(-lf_2spot)*lf_dist
    no_shadow hollow
  }
  #declare lf_flares_drawn = lf_flares_drawn + 1

  #declare lf_new_disc_size = disc_size + .001 * lf_flares_drawn
  disc {
    #declare lf_bound_y = ring_size*0.9/2
    <0,0,0>, z, lf_bound_y
    texture {
      // *****************************************************************
      // ***************** camcorder xtra large spot *********************
      // *****************************************************************
      pigment {
        wood
        color_map {
           [ 0.0              color <1,.5,.5> transmit 1          ]
           [ ring_size*0.65   color <1,.5,.5> transmit .99        ]
           [ ring_size*0.85   color <1,.5,.5> transmit spot_tr]
           [ ring_size*0.90   color <1,.5,.5> transmit 1          ]
           [ 1 color rgbt <0,0,0,1> ]
        }
      }
      finish { lf_Finish }
    }
    // *****************************************************************
    // ** calculate the apparant position of the flare spot
    // *****************************************************************
    #declare lf_2spot = lf_2light + (lf_newctr - lf_2light) * 1.8

    scale lf_new_disc_size * flare_size

    #if (flare_auto_rotate = false)
      rotate lf_rotate_up
    #else
      rotate lf_rotate_ctr
    #end
    rotate lf_rotate_x
    rotate lf_rotate_z

    #declare lf_dist = 1/( vdot(lf_2spot,lf_2ctr)/(vlength(lf_2ctr)*vlength(lf_2spot)) )
    translate cam_loc + lf_new_disc_size * vnormalize(-lf_2spot)*lf_dist
    no_shadow hollow
  }
  #declare lf_flares_drawn = lf_flares_drawn + 1
#end #end


#end  // if light was behind camera, lens flare was skipped.

#end  // if necessary items weren't defined, the lens flare was skipped.

