Path: utzoo!attcan!uunet!seismo!sundc!pitstop!sun!amdcad!ames!vsi1!wyse!mips!koblas From: koblas@mips.COM (David Koblas) Newsgroups: comp.graphics Subject: Better Lighting model for MTV raytracer Message-ID: <4268@wright.mips.COM> Date: 30 Sep 88 18:56:37 GMT Reply-To: koblas@mips.COM (David Koblas) Organization: MIPS Computer Systems, Sunnyvale, CA Lines: 1203 A better shading model for the MTV raytracer [I probably should have posted this a while back, while I was sure it all worked] The two big changes this has are a better shading model, including doing something diffrent with diffuse reflection. You can specify the color of a light, and surfaces have an ambiant and absorbance values [default: no ambiant and no absorbtion]. The "shine" value is now in the range from 0.0 -> 1.0 instead of 0 -> infinity. On balls I ran a sed script like this: '/^f/s/ 35 / 0.2 /' and got close the the same results. Also all componants of a surface can be specified with r,g,b values. Give it a try, and if you have any bugs/problems/sugestions, let me know and I'll give them a try/fix. name : David Koblas place: MIPS Computers Systems phone: 408-991-0287 uucp : {ames,decwrl,pyramid,wyse}!mips!koblas quote: I've began to wonder if X11 is really a competition to see who can create the largest copyright that says, "It's free." ----Patches Begin here------------------------------------------------------- diff -c mtv_raytracer/Makefile mtv_raytracer/ORIG/Makefile *** mtv_raytracer/Makefile Sat Sep 17 17:51:35 1988 --- mtv_raytracer/ORIG/Makefile Thu Sep 15 01:43:29 1988 *************** *** 7,18 **** # directly.... # - SUFFIX=.o PROG=ray CC=cc #CC=gcc ! CFLAGS=-O2 -DNO_VOID $(SYSFLAGS) ! #CFLAGS=-g -DNO_VOID #CFLAGS=-O -DFAST_MATH_PRIMS -finline-functions -g -p YFLAGS=-d --- 7,17 ---- # directly.... # PROG=ray CC=cc #CC=gcc ! CFLAGS=-O2 -DNO_VOID ! #CFLAGS=-O -f68881 #CFLAGS=-O -DFAST_MATH_PRIMS -finline-functions -g -p YFLAGS=-d *************** *** 19,29 **** CSRC=data.c main.c sphere.c vector.c shade.c trace.c intersect.c\ screen.c pic.c poly.c bound.c error.c pqueue.c cone.c\ color.c ! COBJ= data$(SUFFIX) main$(SUFFIX) sphere$(SUFFIX) vector$(SUFFIX) \ ! shade$(SUFFIX) trace$(SUFFIX) intersect$(SUFFIX) screen$(SUFFIX) \ ! pic$(SUFFIX) poly$(SUFFIX) bound$(SUFFIX) error$(SUFFIX) \ ! pqueue$(SUFFIX) cone$(SUFFIX) color$(SUFFIX) ! NFFFILES=balls.nff DOCFILES=README ray.1 COPYING BIBLIO ALGORITHMS OSRC=nff.y tokens.l --- 18,26 ---- CSRC=data.c main.c sphere.c vector.c shade.c trace.c intersect.c\ screen.c pic.c poly.c bound.c error.c pqueue.c cone.c\ color.c ! COBJ=data.o main.o sphere.o vector.o shade.o trace.o intersect.o\ ! screen.o pic.o poly.o bound.o error.o pqueue.o cone.o\ ! color.o NFFFILES=balls.nff DOCFILES=README ray.1 COPYING BIBLIO ALGORITHMS OSRC=nff.y tokens.l diff -c mtv_raytracer/balls.nff mtv_raytracer/ORIG/balls.nff *** mtv_raytracer/balls.nff Fri Sep 16 20:49:18 1988 --- mtv_raytracer/ORIG/balls.nff Thu Sep 15 01:42:52 1988 *************** *** 15,21 **** -12 12 -.5 -12 -12 -.5 12 -12 -.5 ! f SteelBlue .5 .5 0.05 0 0 s 0 0 0 .5 s .272166 .272166 .544331 .166667 s .643951 .172546 1.11022e-16 .166667 --- 15,21 ---- -12 12 -.5 -12 -12 -.5 12 -12 -.5 ! f SteelBlue .5 .5 3 0 0 s 0 0 0 .5 s .272166 .272166 .544331 .166667 s .643951 .172546 1.11022e-16 .166667 diff -c mtv_raytracer/config.h mtv_raytracer/ORIG/config.h *** mtv_raytracer/config.h Thu Sep 15 21:38:33 1988 --- mtv_raytracer/ORIG/config.h Thu Sep 15 01:42:53 1988 *************** *** 23,33 **** #define YMAX (1024) #define MAXLIGHTS (10) #define MAXPRIMS (40000) ! #define MAXLEVEL (9) ! ! #define NLAMBDA (3) ! #define FALSE (0) ! #define TRUE (1) /*********************************************************************** * If your compiler doesn't grok the void type, then define NO_VOID --- 23,29 ---- #define YMAX (1024) #define MAXLIGHTS (10) #define MAXPRIMS (40000) ! #define MAXLEVEL (5) /*********************************************************************** * If your compiler doesn't grok the void type, then define NO_VOID diff -c mtv_raytracer/data.c mtv_raytracer/ORIG/data.c *** mtv_raytracer/data.c Thu Sep 15 20:04:13 1988 --- mtv_raytracer/ORIG/data.c Thu Sep 15 01:42:53 1988 *************** *** 37,43 **** int totalQueues = 0 ; int totalQueueResets = 0 ; int tickflag = 0 ; - int depthflag = 0 ; int nChecked = 0 ; int nEnqueued = 0 ; int nShadowCacheHits = 0 ; --- 37,42 ---- Only in mtv_raytracer: data.o diff -c mtv_raytracer/defs.h mtv_raytracer/ORIG/defs.h *** mtv_raytracer/defs.h Sat Sep 17 17:52:36 1988 --- mtv_raytracer/ORIG/defs.h Thu Sep 15 01:42:54 1988 *************** *** 41,49 **** #define VecAddS(A,a,b,c) (c)[0]=(A)*(a)[0]+(b)[0];\ (c)[1]=(A)*(a)[1]+(b)[1];\ (c)[2]=(A)*(a)[2]+(b)[2] - #define VecMult(A,a,b) (b)[0]=(A)*(a)[0];\ - (b)[1]=(A)*(a)[1];\ - (b)[2]=(A)*(a)[2] #define VecCross(a,b,c) (c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1];\ (c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2];\ (c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0] --- 41,46 ---- *************** *** 59,73 **** Point D ; } Ray ; - typedef struct { - Vec origin,direction; - char flags[NLAMBDA]; - Flt weight[NLAMBDA]; - Flt ior[NLAMBDA]; - Flt trans[NLAMBDA]; - Flt intensity[NLAMBDA]; - } SuperRay; - #define RayPoint(ray,t,point) VecAddS(t,(ray)->D,(ray)->P,point) #define max(a,b) ((a)>(b)?(a):(b)) --- 56,61 ---- *************** *** 76,94 **** /*----------------------------------------------------------------------*/ typedef struct t_surface { ! Flt surf_color[NLAMBDA]; ! Flt surf_ambiant[NLAMBDA]; ! Flt surf_kd[NLAMBDA] ; ! Flt surf_ks[NLAMBDA] ; ! Flt surf_shine[NLAMBDA] ; ! Flt surf_kt[NLAMBDA] ; ! Flt trans[NLAMBDA] ; ! Flt ior[NLAMBDA] ; } Surface ; typedef struct t_light { Vec light_pos ; ! Flt intensity[NLAMBDA]; struct t_object * light_obj_cache[MAXLEVEL] ; } Light ; --- 64,80 ---- /*----------------------------------------------------------------------*/ typedef struct t_surface { ! Color surf_color ; ! Flt surf_kd ; ! Flt surf_ks ; ! Flt surf_shine ; ! Flt surf_kt ; ! Flt surf_ior ; } Surface ; typedef struct t_light { Vec light_pos ; ! Flt light_brightness ; struct t_object * light_obj_cache[MAXLEVEL] ; } Light ; diff -c mtv_raytracer/extern.h mtv_raytracer/ORIG/extern.h *** mtv_raytracer/extern.h Thu Sep 15 20:03:54 1988 --- mtv_raytracer/ORIG/extern.h Thu Sep 15 01:42:54 1988 *************** *** 23,29 **** extern int totalQueues ; extern int totalQueueResets ; extern int tickflag ; - extern int depthflag ; extern int nChecked ; extern int nEnqueued ; extern int nShadowCacheHits ; --- 23,28 ---- diff -c mtv_raytracer/main.c mtv_raytracer/ORIG/main.c *** mtv_raytracer/main.c Fri Sep 16 20:35:45 1988 --- mtv_raytracer/ORIG/main.c Thu Sep 15 01:42:55 1988 *************** *** 16,24 **** #include #include "defs.h" #include "extern.h" - #ifdef SYSV - #define rindex strrchr - #endif main(argc, argv) int argc ; --- 16,21 ---- *************** *** 27,33 **** extern int optind ; extern char *optarg ; int c ; - int resolution = -1 ; char * infilename = NULL ; char * outfilename = "out.pic" ; struct tms pbuf, tbuf ; --- 24,29 ---- *************** *** 37,43 **** else Progname ++ ; ! while ((c = getopt(argc, argv, "do:i:tr:")) != EOF) { switch (c) { case 'o': outfilename = optarg ; --- 33,39 ---- else Progname ++ ; ! while ((c = getopt(argc, argv, "o:i:t")) != EOF) { switch (c) { case 'o': outfilename = optarg ; *************** *** 45,56 **** case 'i': infilename = optarg ; break ; - case 'r': - resolution = atoi(optarg); - break; - case 'd': - depthflag = 1 ; - break; case 't': tickflag = 1 ; break ; --- 41,46 ---- *************** *** 61,68 **** } } ReadSceneFile(infilename) ; - if ( resolution > 0 ) - Xresolution = Yresolution = resolution ; InitSlabs() ; BuildBoundingSlabs() ; times(&pbuf) ; --- 51,56 ---- diff -c mtv_raytracer/nff.y mtv_raytracer/ORIG/nff.y *** mtv_raytracer/nff.y Sat Sep 17 20:12:48 1988 --- mtv_raytracer/ORIG/nff.y Thu Sep 15 01:42:57 1988 *************** *** 15,27 **** %union { Vec vec ; Vec * vecl ; - Flt rgbv[NLAMBDA]; double flt ; } ; %type point primcolor TOKEN %type num - %type rgbvec %% --- 15,25 ---- *************** *** 30,38 **** { int i, l ; for (l = 0 ; l < nLights ; l++) { ! for (i=0;i surf_color) ; ! for (i=0;i surf_kd[i] = $3[i] ; ! CurrentSurface -> surf_ks[i] = $4[i] ; ! CurrentSurface -> surf_shine[i] = $5[i] ; ! CurrentSurface -> surf_kt[i] = $6[i] ; ! CurrentSurface -> ior[i] = $7[i] ; ! CurrentSurface -> surf_ambiant[i] = $8[i] ; ! if ($9[i]==0.0) ! CurrentSurface -> trans[i]= 1.0 ; ! else ! CurrentSurface -> trans[i]= pow(0.5,1.0/$9[i]) ; ! } ! } ! | SURFACE primcolor rgbvec rgbvec rgbvec rgbvec rgbvec ! { /* this is the nff compatible line */ ! int i; ! ! CurrentSurface = (Surface *) malloc (sizeof(Surface)) ; ! VecCopy($2, CurrentSurface -> surf_color) ; ! for (i=0;i surf_kd[i] = $3[i] ; ! CurrentSurface -> surf_ks[i] = $4[i] ; ! CurrentSurface -> surf_shine[i] = $5[i] ; ! CurrentSurface -> surf_kt[i] = $6[i] ; ! CurrentSurface -> ior[i] = $7[i] ; ! CurrentSurface -> surf_ambiant[i] = 0.0 ; ! CurrentSurface -> trans[i] = 1.0 ; ! } } ; cone: --- 86,100 ---- } ; surface: ! SURFACE primcolor num num num num num { CurrentSurface = (Surface *) malloc (sizeof(Surface)) ; VecCopy($2, CurrentSurface -> surf_color) ; ! CurrentSurface -> surf_kd = $3 ; ! CurrentSurface -> surf_ks = $4 ; ! CurrentSurface -> surf_shine = $5 ; ! CurrentSurface -> surf_kt = $6 ; ! CurrentSurface -> surf_ior = $7 ; } ; cone: *************** *** 200,227 **** $$[0] = $1 ; $$[1] = $2 ; $$[2] = $3 ; - } ; - - rgbvec: - '{' num ',' num ',' num '}' - { - $$[0] = $2; - $$[1] = $4; - $$[2] = $6; - } - | TOKEN - { - char buf[80] ; - - if (LookupColorByName(yytext, $$) == 0) { - sprintf(buf, "cannot find color \"%s\"\n", - yytext) ; - yyerror(buf) ; - } - } - | num - { - $$[0] = $$[1] = $$[2] = $1 ; } ; pointlist: --- 154,159 ---- diff -c mtv_raytracer/ray.1 mtv_raytracer/ORIG/ray.1 *** mtv_raytracer/ray.1 Thu Sep 15 20:09:16 1988 --- mtv_raytracer/ORIG/ray.1 Thu Sep 15 01:43:00 1988 *************** *** 14,21 **** .B \-o outputfile ] [ .B \-t - ] [ - .B \-d ] .SH DESCRIPTION This program is an attempt at writing a reasonably useful --- 14,19 ---- *************** *** 30,39 **** .B \-t flag makes the ray tracer output a period after every scanline for those of you who get impatient, or who are wondering if it is still working. - .PP - The - .B \-d - flag prints onto 'stdout' a display of recursion depths. .PP Use .B \-i file --- 28,33 ---- diff -c mtv_raytracer/screen.c mtv_raytracer/ORIG/screen.c *** mtv_raytracer/screen.c Sat Sep 17 18:00:52 1988 --- mtv_raytracer/ORIG/screen.c Thu Sep 15 01:43:01 1988 *************** *** 23,37 **** char *picfile ; int xres, yres ; { ! Pixel *buf, *oldbuf, *curbuf, *tmp ; ! Pic *pic, *PicOpen(); ! Point viewvec, leftvec ; int red, green, blue ; ! Point dir ; ! SuperRay sray; ! Color color; ! Flt frustrumwidth ; ! int x, y, i, m ; /* * open the picture file... --- 23,37 ---- char *picfile ; int xres, yres ; { ! Pixel *buf, *oldbuf, *curbuf, *tmp ; ! Pic *pic, *PicOpen(); ! Point viewvec, leftvec ; int red, green, blue ; ! Point dir ; ! Ray ray ; ! Color color; ! Flt frustrumwidth ; ! int x, y ; /* * open the picture file... *************** *** 58,73 **** VecCross(view -> view_up, viewvec, leftvec); VecNormalize(leftvec); ! VecCopy(view -> view_from, sray.origin); frustrumwidth = (view -> view_dist) * ((Flt) tan(view -> view_angle)) ; - for (i=0;i view_up, viewvec, leftvec); VecNormalize(leftvec); ! VecCopy(view -> view_from, ray.P); frustrumwidth = (view -> view_dist) * ((Flt) tan(view -> view_angle)) ; for (y=0; y < yres + 1; y++) { for (x = 0; x < xres + 1; x++) { VecComb(-frustrumwidth*(2.0*(Flt)y/(Flt)(yres-1)-1.0), *************** *** 74,91 **** view -> view_up, frustrumwidth*(2.0*(Flt)x/(Flt)(xres-1)-1.0), leftvec, dir); ! VecAdd(dir, viewvec, sray.direction); ! VecNormalize(sray.direction); ! for (i=0;i 1.0) color[0] = 1.0 ; if (color[1] > 1.0) color[1] = 1.0 ; if (color[2] > 1.0) color[2] = 1.0 ; --- 68,77 ---- view -> view_up, frustrumwidth*(2.0*(Flt)x/(Flt)(xres-1)-1.0), leftvec, dir); ! VecAdd(dir, viewvec, ray.D); ! VecNormalize(ray.D); ! Trace(0, 1.0, &ray, color); if (color[0] > 1.0) color[0] = 1.0 ; if (color[1] > 1.0) color[1] = 1.0 ; if (color[2] > 1.0) color[2] = 1.0 ; *************** *** 117,124 **** curbuf = (Pixel *) malloc ((xres + 1) * sizeof (Pixel)) ; } - if (depthflag) - putchar('\n'); if (tickflag) fprintf(stderr, ".") ; } --- 103,108 ---- diff -c mtv_raytracer/shade.c mtv_raytracer/ORIG/shade.c *** mtv_raytracer/shade.c Sat Sep 17 19:54:09 1988 --- mtv_raytracer/ORIG/shade.c Thu Sep 15 01:43:01 1988 *************** *** 1,8 **** ! /* +------------------------------------------------------------------+ */ ! /* | Copyright 1988, David Koblas. | */ ! /* | You may copy this file in whole or in part as long as you | */ ! /* | don't try to make money off it, or pretend that you wrote it. | */ ! /* +------------------------------------------------------------------+ */ #include #include --- 1,23 ---- ! /*********************************************************************** ! * $Author: markv $ ! * $Revision: 1.2 $ ! * $Date: 88/09/12 12:58:01 $ ! * $Log: shade.c,v $ ! * Revision 1.2 88/09/12 12:58:01 markv ! * Added specular reflections and shadow caching. When a object ! * is found between a light source and the current point we are trying ! * to shade, that object is cached (indexed by recursion level) in the ! * lightsource. Next time we test a shadow against the light source, ! * we test this object first. If it is between us and the light source, ! * we can correctly shadow the object without calling Intersect(). ! * ! * Note: specular highlights call the unix pow() function, which seems ! * to be REALLY expensive. Optimizations could be made here. ! * ! * Revision 1.1 88/09/11 11:00:44 markv ! * Initial revision ! * ! ***********************************************************************/ #include #include *************** *** 9,325 **** #include "defs.h" #include "extern.h" ! /* ! ** ToDo: ! ** Currently the "shinieness" of a object is only dependant on 1st lambda ! ** ! ** Add SpecularTransmission (once I figure out exactly what it is) ! ** and DiffuseTransmission (once I figure out exactly what it is as well) ! ** ! */ ! /* ! ** And now for your viewing plesure some of the worst comments from another ! ** raytracer that I once knew [I shant tell you the author of this code] ! ** (these are included here, to show people how not to comment narly code) ! ** ! *** | I've not been looking forward to commenting this ! *** | please excuse it if it is ugly. (if it was hard ! *** | to write...) ! ** ! *** | gets amount of normal that has to be added to ! *** | incident ray to get the proper angle of ! *** | refraction by ancient mystical methods ! ** ! *** | gets amount of light transmitted ! *** | through ball by mystical methods mentioned ! *** | above. (see nasty physics text for details) ! ** ! ** ...his "mystical methods" were wrong... ! */ ! ! #define REFLECTION ! #define REFRACTION ! #define AMBIANT ! #define SPECULAR_REFLECTION ! #define DIFFUSE_REFLECTION ! #define ABSORBTION ! ! #ifndef lint ! static char rcsid[]="$Header: shade.c,v 1.1 88/09/17 19:53:45 koblas Locked $"; ! #endif ! ! /* ! ** Calculate the intensity of light at a given point. ! ** ! ** paramaters: ! ** level = recursion level ! ** sray = super ray, the ray that we are currently tracing ! ** P = point of contact with object ! ** N = unit normal with the object ! ** hit = object that was hit ! ** ! ** returns: ! ** maximum depth that was traced to (i.e. what the largest level was) ! ** ! */ ! ! Shade(level,sray,P,N,hit) ! int level; ! SuperRay *sray; ! Vec P,N; ! Isect *hit; { ! SuperRay newsray; ! Ray ray; ! Surface *surf = hit -> isect_prim -> o_surf; ! char lflags[NLAMBDA]; ! int i,j; ! Vec R,T; ! Flt beta[NLAMBDA],val[NLAMBDA]; ! Flt n_dot_v,t; ! Isect newhit; ! int count; ! int maxdepth,m; ! level ++; ! maxdepth=level; ! VecCopy(P,newsray.origin); ! ! /* Gee, does it look like someone messed up. ! ** [this should be fixed] ! */ ! for (i=0;iior[i]==0.0) ! beta[i] = HUGE; ! else ! beta[i] = sray->ior[i] / surf->ior[i]; ! } ! fresnal(sray->direction,N,sray->flags,beta,val); ! for (i=0;iior[i]==0.0) ! beta[i] = HUGE; ! else ! beta[i] = surf->ior[i] / sray->ior[i] ; ! } ! ! /* ! ** Reflected ray ! ** [look closely at the "if" before you touch] ! */ ! n_dot_v = VecDot(N,sray->direction); ! t = fabs(1.0/n_dot_v); ! VecMult(2.0,N,R); ! VecMult(t,sray->direction,newsray.direction); ! VecAdd(R,newsray.direction,newsray.direction); ! VecNormalize(newsray.direction); ! VecCopy(newsray.direction,R); ! #ifdef REFLECTION ! count=0; ! for (i=0;iflags[i] && ! ((newsray.weight[i]= ! surf->surf_ks[i]*val[i]*sray->weight[i])>minweight)))) { ! continue; ! } ! newsray.ior[i] = sray->ior[i]; ! newsray.trans[i] = sray->trans[i]; ! newsray.intensity[i] = 0.0; ! count++; ! } ! if (count!=0) { ! nReflected++; ! m=Trace(level,&newsray); ! if (m>maxdepth) maxdepth=m; ! for (i=0;iintensity[i] += surf->surf_ks[i]* ! val[i]* ! newsray.intensity[i]; ! } ! } ! #endif ! #ifdef REFRACTION ! /* ! ** Refracted ray ! ** [look closely at the "if" before you touch] ! */ ! for (i=0;iflags[i] && (val[i]!=1.0); ! newsray.intensity[i] = 0.0; ! newsray.ior[i] = surf->ior[i]; ! newsray.trans[i]= surf->trans[i]; ! } ! for (i=0;isurf_kt[i]* ! (1.0-val[j])*sray->weight[j])>minweight)) ! newsray.flags[j]=TRUE; ! lflags[j]=FALSE; } else { ! newsray.flags[j]=FALSE; } } - - c2 = 1.0 - (1.0 - n_dot_v*n_dot_v)*(b*b); - t = (-1.0*b)*n_dot_v-sqrt(c2); - VecComb(b,sray->direction,t,N,newsray.direction); - VecNormalize(newsray.direction); - - nRefracted++; - m=Trace(level,&newsray); - if (m>maxdepth) maxdepth=m; - for (j=0;jintensity[j] += surf->surf_kt[j]* - (1.0-val[j])* - newsray.intensity[j]; - } } - #endif - #ifdef AMBIANT - /* - ** Ambiant lighting - */ - for (i=0;iflags[i]) continue; - sray->intensity[i] += surf->surf_ambiant[i]* - surf->surf_color[i]; - } - #endif ! VecCopy(P,ray.P); ! for (j=0;jdirection,ray.D,H); ! VecNormalize(H); ! n_dot_h=VecDot(N,H); ! /* (Blinn) + (Cook and Torrance) model for ! ** specular reflection ! */ ! t = 2.0*(n_dot_h/VecDot(sray->direction,H)); ! g = t*n_dot_l; ! t = t*n_dot_v; ! g = min(min(g,t),1.0); ! if ((surf->surf_shine[0]!=0.0) && (n_dot_l!=0.0)) { ! t=n_dot_l*n_dot_l* ! surf->surf_shine[0]*surf->surf_shine[0]; ! t= (t!=0.0) ? ! (exp((n_dot_l*n_dot_l-1.0)/t) / ! (t*n_dot_l*n_dot_l)) : 0.0 ; ! } else ! t=0.0; ! sr = (t*g)/(PI*n_dot_l*n_dot_v); ! ! #if 0 ! /* this need to be in the loop */ ! VecAddS(-beta[i],ray.D,sray->direction,Hp); ! VecMult(1.0/(beta[i]-1.0),Hp,Hp); ! VecNormalize(Hp); ! dt=pow(VecDot(Hp,N),5); ! #endif ! ! for (i=0;iflags[i]) continue; ! ! #ifdef DIFFUSE_REFLECTION ! /* Diffuse Reflection ! */ ! sray->intensity[i]+= ! (surf->surf_kd[i]* ! surf->surf_color[i]* ! Lights[j].intensity[i]*n_dot_l); ! #endif ! #ifdef SPECULAR_REFLECTION ! /* Specular reflection ! */ ! sray->intensity[i]+= ! surf->surf_ks[i]* ! surf->surf_color[i]* ! val[i]* ! Lights[j].intensity[i]*sr; ! #endif ! #if 0 ! /* I've got a bug!, could be due the the piece missing from the loop */ ! /* Specular transmission ! */ ! sray->intensity[i]+= ! surf->surf_kt[i]* ! surf->surf_color[i]* ! val[i]* ! Lights[j].intensity[i]*dt; ! #endif ! } ! } } ! #ifdef ABSORBTION ! VecSub(sray->origin,P,T); ! t=VecLen(T); ! ! for (i=0;iflags[i]) continue; ! sray->intensity[i]*=sray->trans[i]; } - #endif - - return maxdepth; } ! /* ! ** Fresnals law for transmission. ! ** total internal reflection when (*val == 1.0) [IEEE says ok (the compare)] ! ** ! ** Returns in val[] a set of values to determine the amount of light ! ** that is REFLECTED. The rest of the light (1.0-val[]) is ! ** transmitted/refracted/absorbed. ! ** ! */ ! fresnal(I,N,flag,index,val) ! Vec I,N; ! char *flag; ! Flt *index; ! Flt *val; { ! int i; ! Flt cosine2; ! Flt cosine,index2,sine2,TE,TM,temp; ! cosine2 = VecDot(I,N); ! cosine2 = cosine2*cosine2; ! sine2 = 1.0 - cosine2; ! cosine = sqrt(cosine2); ! for (i=0;i= index2) { ! val[i]=1.0; ! continue; ! } ! temp = sqrt(index2 - sine2); ! TE = (cosine - temp) / (cosine + temp); ! TM = (index2*cosine - temp) / (index2*cosine + temp); ! /* polerization is ignored...so average */ ! val[i]=(0.5*(TE*TE+TM*TM)); ! } } --- 24,165 ---- #include "defs.h" #include "extern.h" ! /*********************************************************************** ! * Shade(level, weight, P, N, I, hit, col) ! * ! * Wow! Too many parameters! ! * ! * Shade is the driving force of the raytracer. It calculates the actual ! * luminance at point P, given N, the normal, and I the incident vector. ! * We also pass in the hit, because the normal generating code might need it. ! * The color is returned in col. ! ***********************************************************************/ ! Shade(level, weight, P, N, I, hit, col) ! int level ; ! Flt weight ; ! Vec P, N, I ; ! Isect * hit; ! Color col ; { ! Ray tray ; ! Color tcol ; ! Vec L, H, R ; ! Flt t ; ! Flt diff ; ! Flt spec ; ! #ifdef SHADOW_CACHING ! Object * cached ; ! #endif /* SHADOW_CACHING */ ! Isect nhit ; ! Surface * surf ; ! int l ; ! col[0] = col[1] = col[2] = 0.0 ; ! surf = hit -> isect_prim -> o_surf ; ! for (l = 0; l < nLights; l++) { ! VecSub(Lights[l].light_pos, P, L); ! if (VecDot(N,L) >= 0.0) { ! t = VecNormalize(L); ! VecCopy(P, tray.P); ! VecCopy(L, tray.D); ! nShadows ++ ; ! #ifdef SHADOW_CACHING ! cached = Lights[l].light_obj_cache[level] ; ! if (cached ! && (cached -> o_procs -> intersect) ! (cached, &tray, &nhit) ! && nhit.isect_t < t) { ! /* ! * we are in shadow, continue... ! */ ! nShadowCacheHits ++ ; ! continue ; ! } ! #endif /* SHADOW_CACHING */ ! if (Shadow(&tray, &nhit, t)) { ! diff = VecDot(N,L) * surf -> surf_kd ! * Lights[l].light_brightness ; ! #ifdef SHADOW_CACHING ! Lights[l].light_obj_cache[level] = NULL ; ! #endif /* SHADOW_CACHING */ ! VecAddS(diff, surf -> surf_color, col, col) ; ! SpecularDirection(I, N, R) ; ! VecNormalize(R) ; ! if (surf -> surf_shine > rayeps) { ! spec = VecDot(R,L) ; ! if (spec > rayeps) { ! spec = pow(spec, surf -> surf_shine ) * Lights[l].light_brightness ; ! col[0] += spec ; ! col[1] += spec ; ! col[2] += spec ; ! } ! } } else { ! #ifdef SHADOW_CACHING ! Lights[l].light_obj_cache[level] = ! nhit.isect_prim ; ! #endif /* SHADOW_CACHING */ } + } } ! VecCopy(P, tray.P); ! if(surf -> surf_ks * weight > minweight) { ! nReflected ++ ; ! SpecularDirection(I, N, tray.D); ! VecNormalize(tray.D); ! Trace(level + 1, surf -> surf_ks * weight, &tray, tcol); ! VecAddS(surf -> surf_ks, tcol, col, col); } ! if (surf -> surf_kt * weight > minweight) { ! nRefracted ++ ; ! if (hit -> isect_enter) ! TransmissionDirection(NULL, surf, I, N, tray.D) ; ! else ! TransmissionDirection(surf, NULL, I, N, tray.D) ; ! Trace(level + 1, surf -> surf_kt * weight, &tray, tcol) ; ! VecAddS(surf -> surf_kt, tcol, col, col) ; } } ! /*********************************************************************** ! * SpecularDirection(I, N, R) ! * ! * Given an incident vector I, and the normal N, calculate the ! * direction of the reflected ray R. ! ***********************************************************************/ ! SpecularDirection(I, N, R) ! Vec I, N, R; { ! VecComb(1.0/fabs(VecDot(I,N)), I, 2.0, N, R); ! VecNormalize(R); ! } ! /*********************************************************************** ! * TransmissionDirection(m1, m2, I, N, T) ! * ! * calculates the direction of the transmitted ray ! ***********************************************************************/ ! TransmissionDirection(m1, m2, I, N, T) ! Surface *m1, *m2; ! Vec I, N, T ; ! { ! Flt n1, n2, eta, c1, cs2 ; ! n1 = m1 ? m1 -> surf_ior : 1.0 ; ! n2 = m2 ? m2 -> surf_ior : 1.0 ; ! eta = n1/n2 ; ! c1 = -VecDot(I,N); ! cs2 = 1.0 - eta * eta*(1.0 - c1*c1); ! if (cs2 < 0.0) ! return 0; ! VecComb(eta, I, eta*c1-sqrt(cs2), N, T); ! return(1); } *** mtv_raytracer/trace.c Sat Sep 17 19:56:07 1988 --- mtv_raytracer/ORIG/trace.c Thu Sep 15 01:43:03 1988 *************** *** 1,8 **** ! /* +------------------------------------------------------------------+ */ ! /* | Copyright 1988, David Koblas. | */ ! /* | You may copy this file in whole or in part as long as you | */ ! /* | don't try to make money off it, or pretend that you wrote it. | */ ! /* +------------------------------------------------------------------+ */ #include #include --- 1,15 ---- ! /*********************************************************************** ! * $Author: markv $ ! * $Revision: 1.2 $ ! * $Date: 88/09/12 13:01:15 $ ! * $Log: trace.c,v $ ! * Revision 1.2 88/09/12 13:01:15 markv ! * Fixed Trace to call Intersect with the max dist argument of HUGE. ! * ! * Revision 1.1 88/09/11 11:00:45 markv ! * Initial revision ! * ! ***********************************************************************/ #include #include *************** *** 9,54 **** #include "defs.h" #include "extern.h" ! #ifndef lint ! static char rcsid[]="$Header$"; ! #endif ! ! /* ! ** Trace a raytraced ray ! */ ! ! Trace(level, sray) ! int level; ! SuperRay *sray; { ! Ray ray; ! Vec P,N; ! Isect hit; ! int i; if (level >= maxlevel) { ! for (i=0;iflags[i]) ! sray->intensity[i]=0.0; ! return level; } ! VecCopy(sray->origin ,ray.P); ! VecCopy(sray->direction,ray.D); ! ! nRays ++; ! ! if (Intersect(&ray,&hit,HUGE)) { ! VecAddS(hit.isect_t,ray.D,ray.P,P); ! (*hit.isect_prim->o_procs->normal)(hit.isect_prim,&hit,P,N); ! if ((VecDot(ray.D, N)) >= 0.0) { VecNegate(N); } ! return Shade(level,sray,P,N,&hit); } else { ! for (i=0;iflags[i]) ! sray->intensity[i]=BackgroundColor[i]; ! return level; } } --- 16,47 ---- #include "defs.h" #include "extern.h" ! Trace(level, weight, ray, color) ! int level; ! Flt weight; ! Ray *ray ; ! Color color ; { ! Object *prim ; ! Vec P, N ; ! Isect hit ; if (level >= maxlevel) { ! color[0] = color[1] = color[2] = 0 ; ! return ; } + + nRays ++ ; ! if (Intersect(ray, &hit, HUGE)) { ! prim = hit.isect_prim ; ! RayPoint(ray, hit.isect_t, P); ! (*prim -> o_procs -> normal) (prim, &hit, P, N); ! if ((VecDot(ray->D, N)) >= 0.0) { VecNegate(N); } ! Shade(level, weight, P, N, ray -> D, &hit, color); } else { ! VecCopy(BackgroundColor, color) ; } } -- name : David Koblas place: MIPS Computers Systems phone: 408-991-0287 uucp : {ames,decwrl,pyramid,wyse}!mips!koblas quote: I've began to wonder if X11 is really a competition to see who can create the largest copyright that says, "It's free."