Rendering Notes: 98-02-03 ------------------------- Last program due today, now only project and final. Two finals: One in class, one take home. Each about half-length. Dan Kursten - perception guy (shadow, etc) visiting next week. Specifically next Monday. So why don't we just move the final to next Wednesday. The final largely won't enter into grades; its just there for "bonus points". But you can't blow it off -- Pete wants us to experience it. Don't stress out on the final -- it's better to work on the project and blow off the final. (You must show up) Project: Check out the digital camera from Monica in the main office. Take a photo of something. Then do a simulated image and try to get them to match. Use the MacBeth color checker for camera calibration. It has known reflectivities. Hit it w/incandescent light. Take a photo. Can find the response curve of the camera. Eye: X = Int bar(x)(lambda) L(lambda) d(lambda), etc. Camera: R = Int r(lambda) L(lambda) d(lambda) and r(lambda) is unknown. Can approx w/ a finite-dimensional projection, like: r(lambda) = Sum(b_i f_i(lambda)). Say the spectrum in the program is nine weighted boxes. Ought to be able to go to the Kodak for data, but can't. Bummer. Problem is getting the data (geometric, and photometric). On cheating: don't have wrong physics, then hack in bad numbers so that the bad numbers and the wrong physics cancel out. Steve Parker or Nate has the glass ball. If you find a really cool object that's 20 bucks, Pete'll buy it. Project is due the day before grades are due: Thursday of finals week. FINAL: Wednesday 11 March, 9:50am, LCR. Stuff: In Moulding's cube. The URL: http://www.cs.indiana.edu/hyplan/kuzimmer/IES/IES.html PHOTOMETRIC STUFF (boring) -------------------------- luminance - which we've often called Y (in X,Y,Z scheme). luminance = Y = 683 Int L(lambda) bar{y}(lambda) d(lambda) L(lambda) is "spectral radiance": Int L(lambda) d(lambda) is "radiance". Most radiometric units are densities, and hence have meanings at points. Point: x, Direction: (theta,phi), Wavelength: lambda are all free variables. Radiance is a function of all. Q = energy Radiance units: J/(m^2 sr nm s) - only the French would mix m and nm in the same unit. :) Only two clean discussions of raidance: 1) Cohen & Wallace's radiosity book; chapeter by Hanrahan, discussed in the volume. Diffuse surface: a given point on it, no matter which direction you look at it from, you see the same spectral radiance. This is the fundamental property of a diffuse surface. So you don't have to store an angle-varying radiance when you store it. You just have to store the outgoing power/area. This is called "radiant exitance", 'cause it's radiance that's exiting. This is what's in the file. Radiance is 1/Pi * radiant exitance = Phi(lambda)/(A*Pi) NONDIFFUSE, NONSPECULAR SURFACES (new stuff) -------------------------------- BRDFs: this is by far the most deadly boring part of all of graphics that doesn't have the word "wavelet" in it. Your eye perceives some spectral radiance. That's what you want to compute. There are different radiances coming into the surface point from every direction. There's one radiance coming out in a particular direction (to the eye). L(lambda) = Int L(omega) f(omega) d(omega). Where the omegas are the incoming angles. In a mirror, only the omega reflected matters. In other surfaces, more of the incoming omegas matter. Rewriting in polars: L(lambda) = Int_0^2Pi Int_0^Pi L(theta,phi) f(theta,phi) sin(theta) d(t)d(p) Can set up an experiment: filament with known solid angle (some little Delta omega). Put the eye somewhere and paint the rest of the room black. What you should get at the eye is: L(lambda) = L*(omega,lambda) f(omega) Delta(omega) If you know what color the filament is: L*(omega,lambda), then: f(omega) = L(lambda) / L*(omega,lambda) Delta(omega) f() encodes how what you see changes as you move the filament around. But now, if you move the eye, it all changes. It gets uglier: L(lambda) = L*(omega,lambda) f(omega_in,omega_out,lambda) Delta(omega) f is a function of incident and outgoing angles, and wavelength too. The real functions you observe are symmetric in omega_in,omega_out, but not in the form here. In a minute it will be. Can do an arbitrary transformation, and such arbitrary functions into f() to make the rest of math life prettier: L(omega_out,lambda) = Int_omega L(omega,lambda) f_r(omega,omega_out,lambda) cos(theta) d(omega) Pulled that cos(theta) out of f because we're allowed. f_r() is the SI form of this kind of function. Jim Arvo (thesis online) has a good explanation of why this is the thing to do. The cos() is there because historically they measured irradiance, and they knew that that would go down with cos(theta), so they wanted that to show up in the equation. Arvo argues you should group [ cos(theta) d(omega) ] together and use cos- weighted solid angle or "projected solid angle" instead. f_r(omega,omega_out,lambda) is the BRDF. This appeared in 1986 in a paper by Immel (sp?) -- he was right, but it in SI units, and stuck it in a little section, and doesn't get credit for it. Cagea (sp?) used stupid units but called it "The Rendering Equation" and gets sited all the time. BRDF == Bidirectional Reflectance Distribution Function It's an intergral, so we can hammer it with Monte Carlo and write a really slow program. Which is what we've already done. Examples: Lambertian: f_r(omega,omega_out,lambda) = R(lambda)/Pi [ what we did ] Mirror: f_r(...) = delta(?) R_s / cos(theta) R_s is some kind of specular reflectance delta(?) is a spherical delta aligned to the mirror direction Mirror discussion - you'd think you never really evaluation this, but here's something interesting: L(omega_out,lambda) = L(omega_in,lambda) f_r(omega_in,omega_out,lambda) cos(theta) / p(omega_in) Pick any probability density f'n, p(), you want. Let's do diffuse: p(omega_in) = cos(theta_in)/Pi f_r(...) = R(lambda)/Pi The cosine's cancel, the Pi's cancel, and you get: R(lambda) L(omega_in,lambda) You've hard-coded stuff that cancels out a bunch of terms in the special-case program we've written for diffuse surfaces. Now for Specular Surfaces: Say f_r(...) = delta(?) R_s / cos(theta) p(omega) = delta(?) ==> L(...) = R_s L(omega_in,lambda) Means "send a mirror ray". Two different instances of hardcoding the same equation. IEEE Floating point: Ratio's of Inf's should end up right. Might not work right on Intel boxes. Properties of BRDF: Reciprocity: f_r(omega_out,omega_in,lambda) = f_r(omega_in,omega_out,lambda) Energy Convservation: For All omega_out: Int_omega_in f_r(i,o,l)cos(t)d(w)<=1 Would like some version of Phong that is this way, if possible. alpha is dir bet omega_in and the reflection of omega_out: f_r(...) = K cos^N(alpha) / cos(theta) Don't know what K is: Int_0^2Pi Int_0^Pi/2 cos^N(alpha) sin(phi) d(alpha) d(phi) = (2Pi/N+1) cos^N+1 |_0^Pi/2 = 1, so K = (N+1)/2Pi This might be wrong...? If N==0, then this just averages the hemisphere. This acts as a fuzzy mirror that gets more and more fuzzy as N goes to zero. Want some attenuation coefficient to make it, say, gold-colored. Call it R(lambda), albedo. f_r(...) = [ (N+1)/2Pi cos^N(alpha)/cos(theta) ] R(lambda) Plugging this in L(omega_out,lambda) one notices f_r can vary from 0 to thousands, so we'd have to take zillions of samples. Bad news. So... p(omega_in) = [ (N+1)/2Pi ] cos^N(alpha) / cos(theta) How about: K cos^N(alpha) -> is something you can actually generate samples for Cook did thin lens, and a little bit of jittering rays, had a high-profile thesis and about three papers since then. Simple reflection model in a paper Pete has on the web, along with all the implementation details... Things that measure these are called goneoreflectometers. One at Cornell. Numbers for measured data are not very trustworthy. Cornell folks working on doing this from a bunch of photos. No good reference on BRDFs. On of the bad ones is on the web page. Pete's working on a good one. www.nist.gov has lots of BRDFs for Russian stuff from the CIA. Final: Totally open book, open notes, open neighbor, etc. SEND PETE MAIL w/sched if want to do Radiance talk.