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_volcube.sl < prev    next >
Encoding:
Text File  |  2008-01-23  |  7.8 KB  |  304 lines

  1. /* srf_vol_cube - Brian Steiner - Sony Pictures Imageworks
  2.  
  3.    This shader raytraces a box that is one unit in size,
  4.    and then ray marches through the volume
  5.    StepSize            - distance between sample points.
  6.    StepJitter          - 0-1 jitter the sample position.
  7.    Density             - volume thickes per unit.
  8.    Epsilon             - offset for calculating gradient normal. 
  9.    Vol_Mult, Vol_Offset - animation controls.
  10.    Do_Shading          - if 1, shading will be calculated.
  11.    SurfNormalDepth     - the mixing depth from surface
  12.                          normal to volume normal.
  13.    Additive            - if 1 add samples, if 0 over samples . 
  14.    ShowActiveVol       - if 1 show the active volume instead of density.
  15.    RunShadowPass       - set to 1 if running a shadow pass.
  16. */
  17.  
  18.  
  19.  
  20. /*-----------------------------------------------------*/
  21. /* fnc_traceBox returns an intersection point on a box */
  22. point
  23. fnc_traceBox (float XMin;
  24.           float XMax;
  25.           float YMin;
  26.           float YMax;
  27.           float ZMin;
  28.           float ZMax;
  29.           float idx;
  30.           string refractSpace;)
  31. {
  32.     extern point P;
  33.     extern vector I;
  34.     extern normal N;
  35.     vector Rd,Ro;
  36.     point Ri;
  37.     vector Pn;
  38.     float D,T;
  39.     float TMin = 1000000;
  40.     vector IN;
  41.     normal NN;
  42.  
  43.     IN = normalize(I);
  44.     NN = normalize(N);
  45.     Rd = vtransform(refractSpace,IN);
  46.     Ro = transform(refractSpace,P);
  47.  
  48.     /*plane_z_min*/
  49.     Pn = (0,0,1);
  50.     D = ZMin * -1;
  51.     T = -(Pn . Ro + D) / (Pn . Rd);
  52.     if(T > 0){
  53.     TMin = T;
  54.     Ri = Ro + T*Rd;
  55.     }
  56.     /*plane_z_max*/
  57.     Pn = (0,0,-1);
  58.     D = ZMax;
  59.     T = -(Pn . Ro + D) / (Pn . Rd);
  60.     if(T > 0 && T < TMin){
  61.     TMin = T;
  62.     Ri = Ro + T*Rd;
  63.     }
  64.     /*plane_x_min*/
  65.     Pn = (1,0,0);
  66.     D = XMin * -1;
  67.     T = -(Pn . Ro + D) / (Pn . Rd);
  68.     if(T > 0 && T < TMin){
  69.     TMin = T;
  70.     Ri = Ro + T*Rd;
  71.     }
  72.     /*plane_x_max*/
  73.     Pn = (-1,0,0);
  74.     D = XMax;
  75.     T = -(Pn . Ro + D) / (Pn . Rd);
  76.     if(T > 0 && T < TMin){
  77.     TMin = T;
  78.     Ri = Ro + T*Rd;
  79.     }
  80.     /*plane_y_min*/
  81.     Pn = (0,1,0);
  82.     D = YMin *-1;
  83.     T = -(Pn . Ro + D) / (Pn . Rd);
  84.     if(T > 0 && T < TMin){
  85.     TMin = T;
  86.     Ri = Ro + T*Rd;
  87.     }
  88.     /*plane_y_max*/
  89.     Pn = (0,-1,0);
  90.     D = YMax;
  91.     T = -(Pn . Ro + D) / (Pn . Rd);
  92.     if(T > 0 && T < TMin){
  93.     TMin = T;
  94.     Ri = Ro + T*Rd;
  95.     }
  96.     return Ri;
  97. }
  98.  
  99.  
  100.  
  101. /*--------------------------------------------------*/
  102. /* active_volume - controls animation in the volume */
  103. float
  104. active_volume(point Pos; float vol_mult, vol_offset;)
  105. {
  106.     return (noise((Pos+30.445)*2)-.5+vol_offset)*vol_mult;
  107. }
  108.  
  109.  
  110.  
  111. /*-------------------------------------------------------*/
  112. /* density function will return the final volume density */
  113. float
  114. get_density(point Pos; float vol_mult, vol_offset;)
  115. {
  116.     float dens = 0;
  117.     float activeVol = 0;
  118.     float offset_active = .1;
  119.     float mult_active = 20;
  120.     activeVol = active_volume(Pos,vol_mult,vol_offset);
  121.     dens = pow(1-abs(noise(Pos*7)*2-1),3);
  122.     dens += pow(1-abs(noise((Pos+24.72)*7)*2-1),3);
  123.     return activeVol + (dens-2);
  124. }
  125.  
  126.  
  127. /*--------------------------------------*/
  128. /* normal calculation inside the volume */
  129. normal calcGradeNorm(point Pos; float vol_mult, vol_offset, dens, epsilon;)
  130. {
  131.     normal Nd;
  132.     Nd = normal (get_density(point (xcomp(Pos) - epsilon, ycomp(Pos),
  133.                     zcomp(Pos)),vol_mult,vol_offset) - dens,
  134.          get_density(point (xcomp(Pos),
  135.                     ycomp(Pos) - epsilon, zcomp(Pos)),vol_mult,vol_offset) - dens,
  136.          get_density(point (xcomp(Pos),
  137.                     ycomp(Pos), zcomp(Pos) - epsilon),vol_mult,vol_offset) - dens);
  138.     Nd = ntransform("object","current",Nd);
  139.     return Nd;
  140. }
  141.  
  142.  
  143.  
  144.  
  145. /*-----------------------------------------------*/
  146. /* shading function returns diffuse ans specular */
  147. void get_shading (point Pos;
  148.           normal Nf;
  149.           vector V;
  150.           float Roughness;
  151.           output color diff;
  152.           output color spec;)
  153. {
  154.     extern vector L;
  155.     extern color Cl;
  156.     diff = 0;
  157.     spec = 0;
  158.     illuminance (Pos, Nf, radians(90)){
  159.     diff += Cl * max(0,normalize(L).Nf);
  160.     spec += Cl * specularbrdf(L, Nf, V, Roughness);
  161.     }
  162. }
  163.  
  164.  
  165.  
  166. /*-------------*/
  167. /* nomal mixer */
  168. normal 
  169. fnc_normalMix (normal N1; normal N2; float mixer)
  170. {
  171.     float N1_mag = 1;
  172.     float N2_mag = 1;
  173.     normal NN1 = normalize(N1);
  174.     normal NN2 = normalize(N2);
  175.     normal result; 
  176.     N1_mag *= 1-mixer;
  177.     N2_mag *= mixer;
  178.     result = normalize(NN1 * N1_mag + NN2 * N2_mag);
  179.     return result;
  180. }
  181.  
  182.  
  183.  
  184. /*---------------------------*/
  185. /* main ray marching shader  */
  186. surface
  187. k3d_volcube(float  StepSize       = 1;
  188.          float  StepJitter     = 0;
  189.          float  Density        = 1;
  190.          float  Epsilon        = .001;
  191.          float  Vol_Mult       = 1;
  192.          float  Vol_Offset     = 0;
  193.          float  Do_Shading     = 1;
  194.          float  SurfNormalDepth = .05;
  195.          float  Additive       = 1;
  196.          float  ShowActiveVol  = 0;
  197.          float  RunShadowPass  = 0;
  198.     )
  199. {
  200.     point  inPoint_obj  = transform("object",P);
  201.     point  outPoint_obj = fnc_traceBox(-.501,.501,-.501,.501,-.501,.501,1,"object");
  202.     vector V  = normalize(-I);
  203.     normal Nf = normalize(N);
  204.     float  Roughness    = .21;
  205.     color  diff    = 1;
  206.     color  spec = 0;
  207.     float  vol_length   = length(outPoint_obj-inPoint_obj);
  208.     float  numOfSteps   = vol_length/StepSize;
  209.     vector step_obj     = (outPoint_obj-inPoint_obj)/numOfSteps;
  210.     vector step_cur     = vtransform("object","current",step_obj);
  211.     float  curStep      = 0;
  212.     float  density_sum  = 0;
  213.     color  color_sum    = 0;
  214.     float  shad_sum     = 0;
  215.     float  remainder    = 100;
  216.     float  cur_density  = 0;
  217.     color  cur_color    = 0;
  218.     float  density      = StepSize * Density;
  219.     float  jitter       = (random() - .5) * StepJitter;
  220.     float  cur_depth    = 0;
  221.     point  Pcur_obj     = inPoint_obj + jitter * step_obj;
  222.     point  Pcur        = P  + jitter * step_cur;
  223.  
  224.     Oi = 0;
  225.     Ci = 0;
  226.  
  227.     /*----------------------------*/
  228.     /*     step loop              */
  229.     while(curStep < numOfSteps && density_sum < 1){
  230.     cur_density = 0;
  231.     cur_color = 0;
  232.  
  233.     /*--- Run Density Function ---*/
  234.     if(ShowActiveVol == 1)
  235.         cur_density = active_volume(Pcur_obj,Vol_Mult,Vol_Offset);
  236.     else
  237.         cur_density = get_density(Pcur_obj,Vol_Mult,Vol_Offset);
  238.  
  239.     /*--- If Density > 0 Run The Rest Of The Loop ---*/
  240.     if(cur_density > 0 && RunShadowPass == 0){
  241.         cur_color = cur_density;
  242.         cur_color = 1;
  243.         if(Do_Shading > 0){
  244.         if(cur_depth > 0){
  245.             normal Vol_Nf = calcGradeNorm(Pcur_obj,Vol_Mult,Vol_Offset,
  246.                           cur_density,Epsilon);
  247.             Vol_Nf = normalize(Vol_Nf);
  248.             Nf = fnc_normalMix(Nf,Vol_Nf,clamp(cur_depth/SurfNormalDepth,0,1));
  249.         }
  250.         get_shading(Pcur,Nf,V,Roughness,diff,spec);
  251.         }
  252.         cur_color = (cur_color * diff) + spec*(1,.8,.2);
  253.         
  254.         /*---- if sample is not a full step ----*/
  255.         remainder = numOfSteps - curStep;
  256.         if(remainder < 1){
  257.         cur_density *= remainder;
  258.         } 
  259.  
  260.         cur_density *= density;
  261.         cur_color *= clamp(cur_density,0,1);
  262.  
  263.         /*---- Composite Sample ----*/
  264.         if(Additive > 0){      
  265.                 /* Just Add Up Density */
  266.         density_sum += max(0,cur_density);
  267.         color_sum += clamp(cur_color,color 0, color 1);
  268.         }
  269.         else{
  270.                 /* Do Over Instead of Add */
  271.         cur_color = clamp(cur_color,color 0,color 1);
  272.         cur_density = clamp(cur_density,0,1);
  273.         color_sum = ( cur_color) * (1-density_sum) + color_sum;
  274.         density_sum = (cur_density) * (1-density_sum) + density_sum;
  275.         }
  276.     }
  277.     else {                   
  278.             /* if Shadow Pass */
  279.         if(Additive > 0){
  280.         shad_sum += max(0,cur_density);
  281.         }
  282.         else{ 
  283.         cur_density = clamp(cur_density,0,1);
  284.         shad_sum = (cur_density) * (1-shad_sum) + shad_sum;
  285.         }
  286.         if(shad_sum >= .5){
  287.         density_sum = 1;
  288.         color_sum = 1;
  289.         }
  290.         P = Pcur;           
  291.             /* Displace Point To Current Sample */
  292.     }
  293.     
  294.     /* jump to the next sample point */
  295.     curStep += 1;
  296.     Pcur_obj += step_obj;
  297.     Pcur += step_cur;
  298.     cur_depth += StepSize;
  299.     }
  300.  
  301.     Ci = color_sum;
  302.     Oi = density_sum;
  303. }
  304.