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
///////////////////////////////////////////////////////////////////////////