| CS 176 (Winter 2008) | |
Project 6 Description
|
|
|
|
In this project you will implement two methods for visualization of vector fields. Read and understand van Wijk's paper on image based flow visualization and Zöckler et al's paper on visualization using illuminated stream lines (links are on the website). We have provided some sample vector field datasets for you to use as input, in: http://www.cs.caltech.edu/courses/cs176/projects/project6/input This project is due Monday, March 3rd, 11:59 PM.
Implement the algorithm as summarized in Section 4 of the van Wijk paper: 1. Calculate a distorted grid. You start with a regular grid of size N x N, where N is determined by the resolution of your input data, and then perturb each point of the grid by the corresponding vector. Your vector field isn't changing (yet), so you only need to do this once. 2. Calculate M = 32 noise images according to equation 18 in the paper, for use in step 4. This is also done as a preprocess. 3. Render the distorted grid with the texture you got from step 6. More specifically, you're drawing using the shifted positions but the UV coordinates have not been shifted, they still lie on a regular grid in UV space. 4. On top of this draw the next noise image which you calculated in step 2, alpha blended with a user-inputted alpha value. Cycle through your noise images by frame number; i.e. use image number {frame mod M}. 5. On top of all that, now draw the dye. This amounts to simply drawing a little colored circle somewhere in the frame. Provide a way to add/move "dye sources" with the mouse. 6. Finally, read the current contents of the framebuffer, and use that as your new texture for step 3.
Try to split the project up into separate kernels. First of all you need to be able to evaluate the vector field at any point in space. Second, you need to be able to trace a path. And finally, you'll need to illuminate these paths. You have your vector field data on a regular grid. For a given point inside the bounding box of the domain, the value of the vector field at that point is a trilinear interpolation of the 8 surrounding points. Find those nearest 8 points using modulo arithmetic. To create streamlines, start by placing some number of points throughout the domain using a uniform random distribution. These are the starting points of your streamlines. Then, for each point (x_n), step forward along the flow direction (see below) to find x_{n+1} and draw a line segment. Do this recursively until your curve is longer than some threshold. (Be careful not to get into an infinite loop if the velocity is 0.) To find x_{n+1} you need to do fourth-order Runge-Kutta integration with adaptive time stepping. Please read section 16.1 and 16.2 of Numerical Recipes (http://www.library.cornell.edu/nr/bookcpdf.html) if you're not familiar with the Runge-Kutta method. Now you can draw the steamlines as flat shaded OpenGL lines and see if they look correct, and you will also see that they don't look very pretty. So next, you will do shaded/illuminated lines. As it is said in the paper, OpenGL does not support shaded line primitives. That's why we use texture maps. During the initialization of your program, create a texture map as described in section 3.3 using the lighting model described in section 2. Your texture will look something like this: P(t1, t2) = k_a + k_d * sqrt(1 - (LT)^2)^p + k_s * ( LT*VT - sqrt((1 - LT^2)(1-VT^2)))^n where LT = 2*t1 - 1, VT = 2*t2 - 1. Mess around with the constants until you find values you like (or make them input parameters). To look up into this texture, you need to give OpenGL texture coordinates t1 and t2 that correspond to the definitions of LT and VT above. This is done by using the tangent vector of the line as your texture coordinates, multiplied by the texture transformation matrix defined in section 3.3. Work this through on paper and make sure you understand what this matrix means. Add transparency as described in section 3.6. |