From: markv@pixar.com (Mark VandeWettering) Newsgroups: comp.graphics Subject: Re: How do YOU compute refraction vectors? Date: 22 May 91 18:15:34 GMT Organization: Pixar -- Point Richmond, California Whenever I need a refraction formula, I refer back to Heckbert's way of calculating it. He did a study of how to compute this and wrote up a small paper that was reproduced in some Siggraph course notes which I could not find immediately. The code for it is reproduced in the simple framework that he has in "Intro to Ray Tracing" by Glassner. For those of you who just want the answer.... /* this slightly differs from his code in the book, but is (in principle) * the same */ TransmissionDirection(m1, m2, I, N, T) double m1, m2; /* the index of refraction */ Vector3 I, N, T; /* incoming, normal and Transmitted */ { double eta, c1, cs2 ; eta = n1 / n2 ; c1 = -VecDot(I, N) ; cs2 = 1 - eta * eta * (1 - c1 * c1) ; if (cs2 < 0) return 0 ; /* total internal reflection */ /* * VecComb(a, v1, b, v2, v3) * computes v3 = a * v1 + b * v2, * where a & b are scalars, and v1, v2, v3 are vectors */ VecComb(eta, I, eta * c1 - sqrt(cs2), N, T) ; return 1; } Hope this helps mark /////////////////////////////////////////////////////////////////////////// From: ph@miro.Berkeley.EDU (Paul Heckbert) Newsgroups: comp.graphics Subject: Re: Ray tracing refraction Summary: C code Date: 2 Feb 89 04:54:49 GMT Organization: University of California at Berkeley Here's some C code to compute the refracted ray direction. Aside to Thant: Actually, Snell's law is n1*sin(theta1)=n2*sin(theta2); you were using the reciprocals of the indices of refraction. Below is an excerpt of some notes I wrote for the Intro to Ray Tracing SIGGRAPH tutorial. (These notes are coming out soon as a book from Academic Press, by Glassner, Arvo, Cook, Haines, Hanrahan, and Heckbert. Included in the book is a derivation of the following formulas from Snell's Law, which I would have included here except it's written in eqn and troff and uses paste-up figures). --------------------------------- Below is C code for SpecularDirection and TransmissionDirection, routines which compute secondary ray directions. The following formulas generate unit output vectors if given unit input vectors. /* * SpecularDirection: compute specular direction R from incident direction * I and normal N. * All vectors unit. */ SpecularDirection(I, N, R) Point I, N, R; { VecAddS(-2.*VecDot(I, N), N, I, R); } /* * TransmissionDirection: compute transmission direction T from incident * direction I, normal N, going from medium with refractive index n1 to * medium with refractive index n2, with refraction governed * by Snell's law: n1*sin(theta1) = n2*sin(theta2). * If there is total internal reflection, return 0, else set T and return 1. * All vectors unit. */ TransmissionDirection(n1, n2, I, N, T) double n1, n2; Point I, N, T; { double eta, c1, cs2; eta = n1/n2; /* relative index of refraction */ c1 = -VecDot(I, N); /* cos(theta1) */ cs2 = 1.-eta*eta*(1.-c1*c1); /* cos^2(theta2) */ if (cs2<0.) return 0; /* total internal reflection */ VecComb(eta, I, eta*c1-sqrt(cs2), N, T); return 1; } where double VecDot(A, B) dot product: returns A.B VecComb(a, A, b, B, C) linear combination: C = aA+bB VecAddS(a, A, B, C) add scalar multiple: C = aA+B typedef double Point[3]; /* xyz point data type */ Point A, B, C; double a, b; ------------- Whitted gives formulas for the refracted ray direction in his classic paper on ray tracing: "An Improved Illumination Model for Shaded Display", CACM, June 1980, but the formulas above compute faster. It's a fun exercise in trig and vector algebra to prove that Whitted's formulas are equivalent. Paul Heckbert, CS grad student 508-7 Evans Hall, UC Berkeley UUCP: ucbvax!miro.berkeley.edu!ph Berkeley, CA 94720 ARPA: ph@miro.berkeley.edu ///////////////////////////////////////////////////////////////////////////