home *** CD-ROM | disk | FTP | other *** search
/ Altsys Virtuoso 2.0K / virtuoso_20k.iso / DemoApps / Graphics / Viewers / raytracers / ohta / Source / shade.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-08  |  5.7 KB  |  331 lines

  1. #include <math.h>
  2.  
  3. #include "ray.h"
  4.  
  5. void initdiffuse(),initspecular(),initmirror(),initglass();
  6. struct color diffuse(),specular(),mirror(),glass();
  7.  
  8. double phong();
  9.  
  10. initshade()
  11. {    nshadetab=4;
  12.     shadetab=nalloc(struct shadetab,nshadetab);
  13.     shadetab[0].shadeinitfunc=initdiffuse;
  14.     shadetab[0].shadefunc=diffuse;
  15.     shadetab[0].nparams=6;
  16.     shadetab[1].shadeinitfunc=initspecular;
  17.     shadetab[1].shadefunc=specular;
  18.     shadetab[1].nparams=10;
  19.     shadetab[2].shadeinitfunc=initmirror;
  20.     shadetab[2].shadefunc=mirror;
  21.     shadetab[2].nparams=13;
  22.     shadetab[3].shadeinitfunc=initglass;
  23.     shadetab[3].shadefunc=glass;
  24.     shadetab[3].nparams=17;
  25. }
  26.  
  27. shadow(o,r)
  28. int o;
  29. struct ray r;
  30. {struct intersect i;
  31.     shadowcount++;
  32.     i=intersect(r);
  33.     return i.obj!=o;
  34. }
  35.  
  36. double phong(n,e,li,g)
  37. struct vector n,e,li;
  38. double g;
  39. {struct vector h;
  40. double l,c,t;
  41.     h.x=e.x+li.x;
  42.     h.y=e.y+li.y;
  43.     h.z=e.z+li.z;
  44.     l= -(h.x*n.x+h.y*n.y+h.z*n.z);
  45.     if(l<0)
  46.         return 0.0;
  47.     c=l*l/(h.x*h.x+h.y*h.y+h.z*h.z);
  48.     t=(1-c)/c;
  49.     if(t>10*g)
  50.         return 0;
  51.     return exp(-t/g);
  52. }
  53.  
  54. struct vector nilvect={0.0,0.0,0.0};
  55.  
  56. struct vector reflect(n,u)
  57. struct vector n,u;
  58. {struct vector v;
  59. double p;
  60.     p=2*(n.x*u.x+n.y*u.y+n.z*u.z);
  61.     v.x=u.x-p*n.x;
  62.     v.y=u.y-p*n.y;
  63.     v.z=u.z-p*n.z;
  64.     return v;
  65. }
  66.  
  67. struct vector refract(n,u,ni)
  68. struct vector n,u;
  69. double ni;
  70. {struct vector v;
  71. double p,t;
  72.     p=n.x*u.x+n.y*u.y+n.z*u.z;
  73.     if(p<0)
  74.     {    t=1-(1-p*p)/(ni*ni);
  75.         if(t<=0)
  76.             return nilvect;
  77.         t= -p/ni-sqrt(t);
  78.     }
  79.     else
  80.     {    ni=1/ni;
  81.         t=1-(1-p*p)/(ni*ni);
  82.         if(t<=0)
  83.             return nilvect;
  84.         t= -p/ni+sqrt(t);
  85.     }
  86.     v.x=u.x/ni+t*n.x;
  87.     v.y=u.y/ni+t*n.y;
  88.     v.z=u.z/ni+t*n.z;
  89.     return v;
  90. }
  91.  
  92. void initdiffuse(o)
  93. struct object *o;
  94. {
  95. #ifdef lint
  96.     o=o;
  97. #endif
  98. }
  99.  
  100. void initspecular(o)
  101. struct object *o;
  102. {
  103. #ifdef lint
  104.     o=o;
  105. #endif
  106. }
  107.  
  108. void initmirror(o)
  109. struct object *o;
  110. {    o->flags|=REFLECT;
  111. }
  112.  
  113. void initglass(o)
  114. struct object *o;
  115. {    o->flags|=REFLECT|REFRACT|SELF;
  116. }
  117.  
  118. struct color diffuse(n,r,i)
  119. int n;
  120. struct ray r;
  121. struct intersect i;
  122. {int j;
  123. struct color c;
  124. double l,vx,vy,vz;
  125. struct ray r2;
  126. double *sdparams;
  127. #ifdef lint
  128.     n=n;
  129. #endif
  130.     sdparams=objects[i.obj].sdparams;
  131.     c.r=sdparams[0];
  132.     c.g=sdparams[1];
  133.     c.b=sdparams[2];
  134.     for(j=1;j<lights+1;j++)
  135.     {    r2.a=objects[j].center;
  136.         vx=r.a.x+i.t*r.l.x-r2.a.x;
  137.         vy=r.a.y+i.t*r.l.y-r2.a.y;
  138.         vz=r.a.z+i.t*r.l.z-r2.a.z;
  139.         l=1/sqrt(vx*vx+vy*vy+vz*vz);
  140.         vx*=l;
  141.         vy*=l;
  142.         vz*=l;
  143.         r2.obj=j;
  144.         r2.l.x=vx;
  145.         r2.l.y=vy;
  146.         r2.l.z=vz;
  147.         l= -(i.n.x*vx+i.n.y*vy+i.n.z*vz);
  148.         if(l>0&&!shadow(i.obj,r2))
  149.         {    c.r+=l*sdparams[3];
  150.             c.g+=l*sdparams[4];
  151.             c.b+=l*sdparams[5];
  152.         }
  153.     }
  154.     return c;
  155. }
  156.  
  157. struct color specular(n,r,i)
  158. int n;
  159. struct ray r;
  160. struct intersect i;
  161. {int j;
  162. struct color c;
  163. double l,x,y,z,sp;
  164. struct ray r2;
  165. struct vector e,li;
  166. double *sdparams;
  167. #ifdef lint
  168.     n=n;
  169. #endif
  170.     sdparams=objects[i.obj].sdparams;
  171.     c.r=sdparams[0];
  172.     c.g=sdparams[1];
  173.     c.b=sdparams[2];
  174.     x=r.a.x+i.t*r.l.x;
  175.     y=r.a.y+i.t*r.l.y;
  176.     z=r.a.z+i.t*r.l.z;
  177.     e.x=x-objects[0].center.x;
  178.     e.y=y-objects[0].center.y;
  179.     e.z=z-objects[0].center.z;
  180.     l=1/sqrt(e.x*e.x+e.y*e.y+e.z*e.z);
  181.     e.x*=l;
  182.     e.y*=l;
  183.     e.z*=l;
  184.     for(j=1;j<lights+1;j++)
  185.     {    r2.a=objects[j].center;
  186.         li.x=x-r2.a.x;
  187.         li.y=y-r2.a.y;
  188.         li.z=z-r2.a.z;
  189.         l=1/sqrt(li.x*li.x+li.y*li.y+li.z*li.z);
  190.         li.x*=l;
  191.         li.y*=l;
  192.         li.z*=l;
  193.         r2.obj=j;
  194.         r2.l=li;
  195.         l= -(i.n.x*li.x+i.n.y*li.y+i.n.z*li.z);
  196.         if(l>0&&!shadow(i.obj,r2))
  197.         {    c.r+=l*sdparams[3];
  198.             c.g+=l*sdparams[4];
  199.             c.b+=l*sdparams[5];
  200.             sp=phong(i.n,e,li,sdparams[9]);
  201.             c.r+=sp*sdparams[6];
  202.             c.g+=sp*sdparams[7];
  203.             c.b+=sp*sdparams[8];
  204.         }
  205.     }
  206.     return c;
  207. }
  208.  
  209. struct color mirror(n,r,i)
  210. int n;
  211. struct ray r;
  212. struct intersect i;
  213. {int j;
  214. struct color c,rc;
  215. double l,x,y,z,sp;
  216. struct ray r2;
  217. struct vector e,li;
  218. double *sdparams;
  219.     sdparams=objects[i.obj].sdparams;
  220.     c.r=sdparams[0];
  221.     c.g=sdparams[1];
  222.     c.b=sdparams[2];
  223.     x=r.a.x+i.t*r.l.x;
  224.     y=r.a.y+i.t*r.l.y;
  225.     z=r.a.z+i.t*r.l.z;
  226.     e.x=x-objects[0].center.x;
  227.     e.y=y-objects[0].center.y;
  228.     e.z=z-objects[0].center.z;
  229.     l=1/sqrt(e.x*e.x+e.y*e.y+e.z*e.z);
  230.     e.x*=l;
  231.     e.y*=l;
  232.     e.z*=l;
  233.     for(j=1;j<lights+1;j++)
  234.     {    r2.a=objects[j].center;
  235.         li.x=x-r2.a.x;
  236.         li.y=y-r2.a.y;
  237.         li.z=z-r2.a.z;
  238.         l=1/sqrt(li.x*li.x+li.y*li.y+li.z*li.z);
  239.         li.x*=l;
  240.         li.y*=l;
  241.         li.z*=l;
  242.         r2.obj=j;
  243.         r2.l=li;
  244.         l= -(i.n.x*li.x+i.n.y*li.y+i.n.z*li.z);
  245.         if(l>0&&!shadow(i.obj,r2))
  246.         {    c.r+=l*sdparams[3];
  247.             c.g+=l*sdparams[4];
  248.             c.b+=l*sdparams[5];
  249.             sp=phong(i.n,e,li,sdparams[9]);
  250.             c.r+=sp*sdparams[6];
  251.             c.g+=sp*sdparams[7];
  252.             c.b+=sp*sdparams[8];
  253.         }
  254.     }
  255.     r2.obj=i.obj;
  256.     r2.a.x=x;
  257.     r2.a.y=y;
  258.     r2.a.z=z;
  259.     r2.l=reflect(i.n,r.l);
  260.     rc=trace(n+1,r2);
  261.     c.r+=rc.r*sdparams[10];
  262.     c.g+=rc.g*sdparams[11];
  263.     c.b+=rc.b*sdparams[12];
  264.     return c;
  265. }
  266.  
  267. struct color glass(n,r,i)
  268. int n;
  269. struct ray r;
  270. struct intersect i;
  271. {int j;
  272. struct color c,rc;
  273. double l,x,y,z,sp;
  274. struct ray r2;
  275. struct vector e,li;
  276. double *sdparams;
  277.     sdparams=objects[i.obj].sdparams;
  278.     c.r=sdparams[0];
  279.     c.g=sdparams[1];
  280.     c.b=sdparams[2];
  281.     x=r.a.x+i.t*r.l.x;
  282.     y=r.a.y+i.t*r.l.y;
  283.     z=r.a.z+i.t*r.l.z;
  284.     e.x=x-objects[0].center.x;
  285.     e.y=y-objects[0].center.y;
  286.     e.z=z-objects[0].center.z;
  287.     l=1/sqrt(e.x*e.x+e.y*e.y+e.z*e.z);
  288.     e.x*=l;
  289.     e.y*=l;
  290.     e.z*=l;
  291.     for(j=1;j<lights+1;j++)
  292.     {    r2.a=objects[j].center;
  293.         li.x=x-r2.a.x;
  294.         li.y=y-r2.a.y;
  295.         li.z=z-r2.a.z;
  296.         l=1/sqrt(li.x*li.x+li.y*li.y+li.z*li.z);
  297.         li.x*=l;
  298.         li.y*=l;
  299.         li.z*=l;
  300.         r2.obj=j;
  301.         r2.l=li;
  302.         l= -(i.n.x*li.x+i.n.y*li.y+i.n.z*li.z);
  303.         if(l>0&&!shadow(i.obj,r2))
  304.         {    c.r+=l*sdparams[3];
  305.             c.g+=l*sdparams[4];
  306.             c.b+=l*sdparams[5];
  307.             sp=phong(i.n,e,li,sdparams[9]);
  308.             c.r+=sp*sdparams[6];
  309.             c.g+=sp*sdparams[7];
  310.             c.b+=sp*sdparams[8];
  311.         }
  312.     }
  313.     r2.obj=i.obj;
  314.     r2.a.x=x;
  315.     r2.a.y=y;
  316.     r2.a.z=z;
  317.     r2.l=reflect(i.n,r.l);
  318.     rc=trace(n+1,r2);
  319.     c.r+=rc.r*sdparams[10];
  320.     c.g+=rc.g*sdparams[11];
  321.     c.b+=rc.b*sdparams[12];
  322.     r2.l=refract(i.n,r.l,sdparams[16]);
  323.     if(r2.l.x==0&&r2.l.y==0&&r2.l.z==0)
  324.         return c;
  325.     rc=trace(n+1,r2);
  326.     c.r+=rc.r*sdparams[13];
  327.     c.g+=rc.g*sdparams[14];
  328.     c.b+=rc.b*sdparams[15];
  329.     return c;
  330. }
  331.