Notes, 98-03-30 --------------- goals are to: come up w/hierarchical radiostiy system at the end of it; will start with the Monte Carlo tracer from pete's class. Mondays will be theory, Wednesdays will be implementations. M's will have HW assignments, W's will have programming ass'ts. Lots of stuff will be open-ended, esp. programming assignments. You might go down the wrong direction. If you do this, just explain why it was the wrong dir., and you might get some extra time. 25% will be HW ass'ts, 25% final, 50% programming. Programming handed in on the web. HW on paper. --- Start w/BG stuff. Basically trying to solve a big integral eqn: L(x,w) = L_e(x,w) + Int_hemi rho(x,w<-w) cos theta_x L(x',w') dw' Int is all energy coming in over hemi, weighted by the cosine at the receiver and weighted by the BRDF. Same deal as radiosity in the RT course. Units for L() are watts/projected-m^2/stradian. The projected-m^2 accounts for the cosine in there. W/m^2 is another name for radiance. The BRDF takes irradiance and converts it back into a radiance. Thinking about this in this kind of a typesafe way makes it easier to keep track of when to use the BRDF. Irradiance is W/m^2 - is the light incident on a surface. It's a surface energy density because it has no direction coordinate. It's defined at a point. When we go to diffuse BRDFs, the direction is less important. I'll keep the direction in, 'cause it's a better way of thinking about it, esp. when you want to generalize to other BRDFs. We're going to need to do things between surfaces, so we need to change that integral to one over surfaces: dw = vis(x,x') cos theta_x dA / d^2 L(x,w) = L_e(x,w) + Int_environment rho(x,w<-w') cos(theta_x)* cos(theta_x')/d^2 * L (x',w) dA Finally, we can make the diffuse assumption, get rid of direction and end up with: L(x) = L_e(x) + rho(x) Int_environment [cos(theta_x) cos(theta_x') / d^2] L(x') dA theta_x is the angle between the line of sight and the normal of the plane on which the energy is incident, x' is the normal from which the energy is coming. We want to solve this integral equation. We have a problem that the set of all radiance functions is an infinite dimensional space. For Monte Carlo, we project L onto the image-space: P_new(L). It's a way of converting down into finite-dimensions and getting something we can display. Radiosity, on the other hand, converts a sol'n over the whole environment by projecting the infinite-dimensional space down onto a mesh: P_mesh(L). The mesh becomes the set of basis functions for the environment. Basis f'ns are a linearly independent set of f'ns that span some larger space of f'ns. Easy analogy is vectors. If you have the vector in R^3, and you want to figure out its x component, you do an inner product with the x basis vector. For f'ns, we define an inner product between a f'n and some basis: = Int_space B_i(x) L(x) dx. So, let's put up some basis f'ns. \/ One set of basis f'ns is the hat f'ns. Choose basis: /\ and you can do piecewise linear, etc. Your choice of basis determines what you can finally represent. Piecewise constant are easier to work with, piecewise linear look better when displayed directly. If we have a set of basis f'ns, B_{0,1,...n}, we can say they're orthogonal iff = 0 i!=j, 1 i==j. The advantage is that bases are independent and separable. Piecewise linear basis as drawn above are not linearly independent. When drawn as y=x, y=-x they're not. When drawn as y=1 and y=x, they are (on interval -1..1). We're gonna have Sum B_i*c_i, and we need some way to get these constants. Like in R^3, we do inner products to determine the projection down onto the basis. In R^3 everything is orthonormal, which means that the inner product of two basis functions is 1 whenever they're the same. For us, this means that energy is conserved. What to do when basis isn't orthogonal or even orthonormal? We come up with a set of functions that are duals to the original basis. The duals are used to extract information out of the f'n so as to build up something as sum of original basis. If we have a set of basis f'ns, B_i, and want to find the c_i's, we need the property, where ~B_i is the dual of B_i that = 0 i!=j, 1 i==j. Ex: let's project constant f'n, 1, onto the hats: B_0 is hat from 0..1, B_1 is hat from 1..4. = 1 = 3 ______ Sum B_i c_i = __| 0 1 2 3 4 This doesn't work 'cause the basis is not orthonormal. So you come up with a set of duals so the property above holds. We invent ~B_0, ~B_1. Let ~B_0 be identical to B_0. Let ~B_1 be 1/3 B_1. Duals are not unique. Is there a principled way to find a nice one? No, not really. You get different types of artefacts when you use different duals. You could have said ~B_1 was 1 on 1..2 and been okay but different. Next basis is the linear interpolation basis: ^^^ VVV 012 Let B_0 be -x on 0..1, B_1 be x on 0..1, B_2 be -x on 1..2, B_3 be x on 1..2. This allows discontinuities at the integers. Here we have a couple of choices for duals. A common one is the "point- sampling dual": ~B_0 = delta(x) - Dirac delta. So here to get the component of the f'n, we just evaluate it at some point. Ex: for finding uv's for non-perp vector v1, v2. Find the dual of v1, it must be perp to v2 and however long it needs to be so that when dotted with v1 it yields zero. The dual of v2 is perp to v1 and however long to make ~v1 dot v1 ==1. Dotting a coord with the duals gives the coord in v1/v2 u,v space. This is cool. So how do we use this? With the MC ray tracer, we can evaluate L at any point x. We've been picking points on the screen, but we could to a little MC simulation at any point. Right now we have the ability to evaluate L(x0) with a fair amount of work. We've been using this ability to project the space onto the screen by doing a little integration over the pixel. Effectively you're treating the pixel as a basis function. You treat it as having a height 1 and area 1 and doing the average over that. For radiosity we want to store stuff on surfaces instead of on the screen. So if you have some set of basis f'ns mesh, you do something similar to what you did in the MC RT. You project down onto the set of basis f'ns that represent the mesh. For the radiosity thing, you pick basis f'ns over all surfaces, and we want to compute the c_i's needed to represent L as accurately as possible using this collection of basis f'ns. If we have a PW constant mesh, we project L onto it by doing: c_i = < ~B_i, L > This is an integration, which is all we were doing for the pixels above, except that ~B_i might be something more fun than PW constant. Basically, we can do a whole bunch of inner products throughout the environment to compute a bunch of c_i's to store on the environment, then when we want to display, we reconstruct Sum c_i B_i to display. This isn't traditional radiosity in that we haven't created a matrix and solved a system. We'll start here, get a picture right away and build up from this. Wednesday we'll talk about how to program this and everything else. HW ass't on web page, due next Monday. Do some inner products, look at what set of basis f'ns to use for Cornell box. Guess what the programming ass't is!