fritzz@net1.UCSD.EDU (Friedrich Knauss) (07/31/86)
Hiya! requests fo the refraction fix have been overwhelming, so I decided to post to the net. First of, it appears that some machines are having problems with the routine scamult() in support.c. Removing the line modifying xzl should fix the problem. (It isn't really needed). Other problems that arise during initialization should work after this refraction mod has been made. Anyway, this routine does refraction properly: (kind of) sin(theta incident)/sin(theta refracted) = ratio of indices of refraction. for your information the refractive index for glass is about 1.5, the refractive index for air is close to 1. I am currently working on getting the amplitudes of refracted and reflected light to be correct. It could be very ugly, and will also include internal reflection. It may take a week or so, depending on how eager I get. I may also start worrying about polarization (blech). Now for the real thing... changes you have to make: 1) in tracer.c: right after the calculation of nob the is a loop that changes the value bl[i].ior. It should be changed to: bl[i].ior = bl[i].ior * bl[i].ior; this saves time doing the multiplication every time you use it later on. 2) in shade.c: delete the routine refract() and replace it with everything after the dotted line down there. That's it. I hope you enjoy playing with it, as it is far from a finished project and has lots of opportunies for playing. Also, if if you are impressed and desparately looking for new employees, I'm currently in the market. ( =)/2 ) good luck and have fun... f ------------------------------------------------------------------ int refract (r, bll) struct ray *r; struct ball *bll; { struct vector new, norm; struct mat trans; double l, refk (); struct sphere ss; sv (&norm, &(r -> org), &(bll -> s.cent)); vecl (&norm); vecl (&(r -> dir)); /* this is it!!*/ /* get the addition factor for the normal */ scamult (refk (&(norm), &(r -> dir), bll -> ior), &norm); av (&(r -> dir), &(r -> dir), &norm); /* find the point where the ray leaves the sphere. just like shade. */ vexzl (&(r -> dir)); vecl (&(r -> dir)); mt (&(r -> dir), &trans); ss.rad = bll -> s.rad; sv (&ss.cent, &(bll -> s.cent), &(r -> org)); l = findo (&trans, &(ss)); mv (l * trans.x.x, l * trans.x.y, l * trans.x.z, &new); av (&(r -> org), &(r -> org), &new); /* redirect the ray and continue tracing */ sv (&norm, &(r -> org), &(bll -> s.cent)); vecl (&norm); vecl (&(r -> dir)); scamult (refk (&(norm), &(r -> dir), 1.0 / bll -> ior), &norm); av (&(r -> dir), &(r -> dir), &norm); return (shade (r)); } double refk (nrm, in, ior) struct vector *nrm, *in; double ior; { double dt, ln, li, ret; dt = dot (nrm, in); ln = nrm -> x * nrm -> x + nrm -> y * nrm -> y + nrm -> z * nrm -> z; li = in -> x * in -> x + in -> y * in -> y + in -> z * in -> z; if (dt < 0) ret = (-dt - sqrt (dt * dt - ln * li * (1 - ior))) / ln; else ret = (-dt + sqrt (dt * dt - ln * li * (1 - ior))) / ln; return (ret); }