home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Multimedia / k3d-setup-0.7.11.0.exe / share / k3d / shaders / surface / k3d_lensflare.sl < prev    next >
Encoding:
Text File  |  2008-01-23  |  7.0 KB  |  228 lines

  1. /****************************************************************************
  2.  * lensflare.sl
  3.  *
  4.  * Description: This shader, when placed on a piece of geometry 
  5.  *   immediately in front of the camera, simulates lens flare.
  6.  *   These effects happen in real cameras when the camera points toward
  7.  *   a bright light source, resulting in interreflections within the
  8.  *   optical elements of the lens system itself.  Real lens flare is
  9.  *   pretty plain looking and uninteresting; this shader takes some
  10.  *   liberties but looks pretty good.
  11.  *   
  12.  * Parameters:
  13.  *   intensity - overall scale of intensity of all lens flare effects
  14.  *   bloomintensity - overall intensity of the "bloom" effect.  Setting
  15.  *          this to 0 removes the bloom effect altogether.
  16.  *   bloomradius, bloomfalloff - control the size & shape of the bloom
  17.  *   bloomstarry, bloomnpoints - control the "starry" appearance of the 
  18.  *          bloom effect (bloomstarry=0 means perfectly round bloom)
  19.  *   starburstintensity - overall intensity of starburst effect (0=none)
  20.  *   starburstradius, starburstnpoints, starburstfalloff - control the
  21.  *          size and shape of the starburst effect
  22.  *   rainbowintensity - intensity of rainbow effect (0=none)
  23.  *   rainbowradius, rainbowwidth - size of the rainbow
  24.  *   nspots - number of "spots" splayed out on the axis joining the
  25.  *          image center with the light position
  26.  *   disky, ringy, blotty, bloony - give the relative proportions of
  27.  *          the 4 different kinds of spots.
  28.  *   spotintensity - overall intensity scale for the spots
  29.  *   spotvarycolor - scale the color variation of the spots
  30.  *   seed - random number seed for many of the computations
  31.  *
  32.  * WARNING: lens flare is notorious as a sign of cheesy, cheap computer
  33.  *   graphics.  Use this effect with extreme care!  
  34.  *
  35.  ***************************************************************************
  36.  *
  37.  * Author: Larry Gritz & Tony Apodaca, 1999
  38.  *
  39.  * Contacts:  lg@pixar.com
  40.  *
  41.  * $Revision: 1.1 $    $Date: 2006/02/25 20:11:54 $
  42.  *
  43.  ****************************************************************************/
  44.  
  45. #include "k3d_patterns.h"
  46.  
  47.  
  48. /* Helper function: compute the aspect ratio of the frame */
  49. float
  50. aspectratio()
  51. {
  52.   uniform point Pcorner0 = transform("NDC", "screen", point(0, 0, 0));
  53.   uniform point Pcorner1 = transform("NDC", "screen", point(1, 1, 0));
  54.   return (xcomp(Pcorner1) - xcomp(Pcorner0)) / (ycomp(Pcorner1) -
  55.                         ycomp(Pcorner0));
  56. }
  57.  
  58.  
  59. /* Helper function: compute the camera's diagonal field of view */
  60. float
  61. cameradiagfov()
  62. {
  63.   uniform vector corner = vector(transform("NDC", "camera", point(1, 1, 0)));
  64.   uniform float halfangle = acos(normalize(corner).vector(0, 0, 1));
  65.   return 2 * halfangle;
  66. }
  67.  
  68.  
  69. color
  70. rainbow(float x, dx)
  71. {
  72. #define R    color(1,0,0)
  73. #define O    color(1,.5,0)
  74. #define Y    color(1,1,0)
  75. #define G    color(0,1,0)
  76. #define B    color(0,0,1)
  77. #define Ii    color(.375,0,0.75)
  78. #define V    color(0.5,0,0.5)
  79.   return filteredpulse(0, 1, x, dx) * spline(x, V, V, Ii, B, G, Y, O, R, R);
  80. }
  81.  
  82.  
  83.  
  84. surface k3d_lensflare(float intensity = 1.0;
  85.               float bloomintensity = 1;
  86.               float bloomradius = 0.5;
  87.               float bloomstarry = 0.75;
  88.               float bloomnpoints = 25;
  89.               float bloomfalloff = 8;
  90.               float starburstintensity = 0.075;
  91.               float starburstradius = 0.5;
  92.               float starburstnpoints = 100;
  93.               float starburstfalloff = 3;
  94.               float rainbowintensity = 0.03;
  95.               float rainbowradius = 0.5; float rainbowwidth = 0.2;
  96.               float nspots = 50; float disky = 3; float ringy = 1;
  97.               float blotty = 1;
  98.               float bloony = 1; float spotintensity = 0.08;
  99.               float spotvarycolor = 0.5; float seed = 143;
  100.   )
  101. {
  102.   uniform float nrand = 0;
  103.   uniform float urand()
  104.   {
  105.     extern uniform float nrand, seed;
  106.     nrand += 1;
  107.     return cellnoise(nrand, seed);
  108.   }
  109.  
  110.  
  111.   Ci = 0;
  112.   Oi = 0;
  113.  
  114.   uniform float aspect = abs(aspectratio());
  115.   uniform float lensfov = cameradiagfov();
  116.  
  117.   point Pndc = (transform("NDC", P) - vector(.5, .5, 0)) * 2;
  118.   Pndc *= vector(aspect, 1, 0);
  119.   float dPndc = filterwidthp(Pndc);
  120.  
  121.   illuminance(P, vector "camera"(0, 0, 1), PI / 2)
  122.   {
  123.     float atten = acos(zcomp(normalize(vector transform("camera", P + L))));
  124.     atten = 1 - smoothstep(1, 2, abs(atten) / (lensfov / 2));
  125.  
  126.     float brightness =
  127.       atten * intensity * (comp(Cl, 0) + comp(Cl, 1) + comp(Cl, 2)) / 3;
  128.  
  129.     color Cflare = 0;
  130.  
  131.     nrand = 0;
  132.     point Plight = (transform("NDC", P + L) - vector(.5, .5, 0)) * 2;
  133.     Plight *= vector(aspect, 1, 0);
  134.  
  135.     vector Lvec = Plight - Pndc;
  136.     float angle = atan(ycomp(Lvec), xcomp(Lvec)) + PI;
  137.  
  138.     /*
  139.      * Handle the image of the lamp.  There are 3 effects:
  140.      * the bloom, a small red ring flare, and the triple starburst.
  141.      */
  142.     float dist = length(Lvec);
  143.  
  144.     if(bloomintensity > 0)
  145.       {
  146.     float radius = sqrt(brightness) * 5 * mix(.2, bloomradius, urand());
  147.     float bloom = pnoise(bloomnpoints * angle / (2 * PI), bloomnpoints);
  148.     bloom = mix(0.5, bloom, bloomstarry);
  149.     bloom = mix(1, bloom, smoothstep(0, 0.5, dist / radius));
  150.     bloom = pow(1 - smoothstep(0.0, radius * bloom, dist), bloomfalloff);
  151.     Cflare += bloom * (bloomintensity / intensity) / brightness;
  152.       }
  153.  
  154.     /* Starburst */
  155.     if(starburstintensity > 0)
  156.       {
  157.     float radius =
  158.       sqrt(brightness) * 5 * mix(.2, starburstradius, urand());
  159.     float star = float pnoise(starburstnpoints * angle / (2 * PI),
  160.                   starburstnpoints);
  161.     star =
  162.       pow(1 - smoothstep(0.0, radius * star, dist), starburstfalloff);
  163.     Cflare += star * (starburstintensity / intensity) / brightness;
  164.       }
  165.  
  166.     /* Rainbow */
  167.     if(rainbowintensity > 0)
  168.       {
  169.     Cflare +=
  170.       brightness * (rainbowintensity / intensity) *
  171.       rainbow((dist / rainbowradius - 1) / rainbowwidth,
  172.           (dPndc / rainbowradius) / rainbowwidth);
  173.       }
  174.  
  175.     /*
  176.      * Now emit the random rings themselves
  177.      */
  178.     vector axis = normalize(vector Plight);
  179.     uniform float i;
  180.     nrand = 20;            /* Reset on purpose! */
  181.     for(i = 0; i < nspots; i += 1)
  182.       {
  183.     uniform float alongaxis = urand();
  184.     point cntr = point(mix(-1.7, 1.7, alongaxis) * axis);
  185.     float axisdist = distance(cntr, Pndc);
  186.     float radius = mix(0.04, .1,
  187.                pow(urand(), 2)) * distance(cntr, Plight);
  188.     color clr = Cl;
  189.     clr *= 1 + spotvarycolor * (color cellnoise(i) - 0.5);
  190.     float bright = 1 - (2 * radius);
  191.     bright *= bright;
  192.  
  193.     uniform float alltypes = (disky + ringy + blotty + bloony);
  194.     uniform float type = urand() * alltypes;
  195.  
  196.  
  197.     float int = 0;
  198.     if(type < disky)
  199.       {            /* Flat disk */
  200.         int = 1 - filterstep(radius, axisdist - dPndc / 2,
  201.                  axisdist + dPndc / 2);
  202.       }
  203.     else if(type < (disky + ringy))
  204.       {            /* Ring */
  205.         int = filteredpulse(radius, radius + 0.05 * axisdist,
  206.                 axisdist, dPndc);
  207.       }
  208.     else if(type < (disky + ringy + blotty))
  209.       {            /* Soft spot */
  210.         int = 1 - smoothstep(0, radius, axisdist);
  211.       }
  212.     else
  213.       {            /* Spot with soft hole in middle */
  214.         int = smoothstep(0, radius, axisdist) - filterstep(radius,
  215.                                    axisdist -
  216.                                    dPndc / 2,
  217.                                    axisdist +
  218.                                    dPndc / 2);
  219.       }
  220.     Cflare += spotintensity * bright * clr * Cs * int;
  221.       }
  222.  
  223.     Ci += Cflare * Cl * atten;
  224.   }
  225.  
  226.   Ci *= intensity;
  227. }
  228.