<!--#set var="name" value="Programming Assignment 2" -->
<!--#include virtual="header.html" -->
<!--
<head><title>COS 526, Fall 2006: Programming Assignment 2</title></head>
<body bgcolor="#ffffff" text="#000000">
<center><h2>COS 526 - Advanced Computer Graphics</h2></center>
-->


<h2>Programming Assignment 2: Light Fields</h2>
<b>Due Tuesday, Nov. 14</b>

<h3>Overview</h3>
<p>
For this assignment, you will implement a light field viewer
based on the techniques described by
<a href="papers/levoy96.pdf">Levoy & Hanrahan 96</a>.

<h3>I. Deriving Equations</h3>
<p>
The basic operation performed by the light field viewer is looking up the
color corresponding to a given ray in space.  Since the light field is
represented by "slabs" (pairs of planes in space), you will need to derive
code for intersecting a ray in space with a rectangular region of a plane
(specified with the region's four corners).
<p>
Hints:
<ul>
<li> Make sure to report "no intersection" if the ray intersects the plane
outside the valid region or if the intersection is behind the viewer.
<li> Once you know the point of intersection, and given that the region is
represented with <i>m</i>x<i>n</i> samples, you will have to find either the
closest sample or, for bilinear interpolation, the four closest samples.
<li> Because light fields sometimes use slabs with planes (especially the
<i>uv</i> plane) at infinity, you should derive your equations such that
they take corners specified in homogeneous coordinates (with the <i>w</i>
coordinate possibly 0).
</ul>

<h3>II. Basic Light Field Viewer (60%)</h3>
<p>
<ol>
<li> Begin with code to read a single-slab, uncompressed light field given
as a pair of files:
<ul>
<li> A "parameters" file that contains the following in plain ASCII format
<pre>
	samples_u samples_v samples_s samples_t

	uv_corner1_x uv_corner1_y uv_corner1_z uv_corner1_w  uv_corner1_p uv_corner1_q
	uv_corner2_x uv_corner2_y uv_corner2_z uv_corner2_w  uv_corner2_p uv_corner2_q
	uv_corner3_x uv_corner3_y uv_corner3_z uv_corner3_w  uv_corner3_p uv_corner3_q
	uv_corner4_x uv_corner4_y uv_corner4_z uv_corner4_w  uv_corner4_p uv_corner4_q

	st_corner1_x st_corner1_y st_corner1_z st_corner1_w  st_corner1_p st_corner1_q
	st_corner2_x st_corner2_y st_corner2_z st_corner2_w  st_corner2_p st_corner2_q
	st_corner3_x st_corner3_y st_corner3_z st_corner3_w  st_corner3_p st_corner3_q
	st_corner4_x st_corner4_y st_corner4_z st_corner4_w  st_corner4_p st_corner4_q
</pre>
For example, the following parameters
<pre>
	16 16  256 256

	-2 -2  2  1   0  0
	 2 -2  2  1   1  0
	 2  2  2  1   1  1
	-2  2  2  1   0  1

	-1 -1  0  1   0  0
	 1 -1  0  1   1  0
	 1  1  0  1   1  1
	-1  1  0  1   0  1
</pre>
specify a light field with 16x16 samples in <i>uv</i> and 256x256 samples in
<i>st</i>.  The lower-left (0,0) corner on the <i>uv</i> plane is at
(-2,-2,2,1), the lower-right (1,0) corner is at (2,-2,2,1), etc.
<p>
<li> A "data" file of length
<tt>samples_u * samples_v * samples_s * samples_t * 3</tt> that contains
the raw <i>uvst</i> data, given as RGB triples.  This is raw binary data
expressed as bytes in RGB order with no padding or line breaks.
In C, you'd read it using something like
<pre>
        FILE *lfdatafile = fopen("data", "rb");
        for (i = 0; i < uwidth*uheight*vwidth*vheight; i++) {
                unsigned char buf[3];
                fread(buf, 3, 1, lfdatafile);
                unsigned char red = buf[0];
                unsigned char green = buf[1];
                unsigned char blue = buf[2];
                /* Do something with the data... */
        }
</pre>
The order of the samples varies fastest in "t", next fastest in "s",
then "v" and "u".  That is, looking at (u,v,s,t) indices, the first
sample is (0,0,0,0), the next one is (0,0,0,1), and so on.

</ul>
<p>
Some sample data files are <a href="lf/simple/">here</a>.

<li> For each frame, do the following:
<ul>
<li> Implement a mouse-based camera controller.
<li> For each pixel, generate a ray starting at the camera position and
in the pixel's direction.
<li> Intersect the ray with the <i>uv</i> and <i>st</i> planes, finding the
closest sample in each.
<li> If both intersections are valid, look up the color for that pixel, else
color the pixel black.
<li> Once all pixels have been assigned a color, use <tt>glDrawPixels()</tt>
to render to the screen.
</ul>
</ol>


<h3>III. Extensions (30%)</h3>
<p>
Implement extensions (A and B) xor C:
<h4>A. Interpolation</h4>
<p>
In addition to the "closest-point" sampling implemented above, implement
the following interpolation schemes:
<ul>
<li> Nearest in <i>uv</i>, bilinear in <i>st</i>.
<li> Bilinear in <i>uv</i>, nearest in <i>st</i>.
<li> Quadrilinear in <i>uvst</i>.
</ul>
<p>
Which of the first 2 appears to produce better results?  Why?

<h4>B. Multiple Slabs</h4>
<p>
Extend your viewer to handle light fields consisting of multiple slabs.
Some data is <a href="lf/multi_slab/">here</a>.


<h4>C. VQ Decompression</h3>
<p>
Extend your system to handle VQ-compressed data.  The changes in the data
format are as follows:
<ul>
<li> The "parameters" file will contain an additional line indicating
the VQ tile size and codebook length.  For example,
<pre>
	1 1 2 2  16384
</pre>
indicates that the VQ tiles have extent 1x1 in <i>uv</i>, 2x2 in <i>st</i>,
and that valid codewords are 0 through 16383.
<li> The "data" file will have length
<pre>
	(samples_u / tilesize_u) * (samples_v / tilesize_v) * 
	(samples_s / tilesize_s) * (samples_t / tilesize_t) * 2
</pre>
with 2-byte codebook indices replacing the raw RGB data.
<li> An additional "codebook" file will contain the VQ codebook entries.
For the example above, there will be 16384 entries, each of length 1*1*2*2*3
(an RGB color for each entry in a 1x1x2x2 tile).
</ul>
<p>
Some data to get you started is <a href="lf/vq/">here</a>.  However,
once you have VQ decompression implemented, it should be possible to view
the <tt>.lif</tt> files available
<a href="http://graphics.stanford.edu/software/lightpack/lifs.html">here</a>.
The only tedious part is parsing the <tt>.lif</tt> header, documented
<a href="http://graphics.stanford.edu/software/lightpack/doc/file_format.html">here</a>.
<p>
Note that for this assignment, it is acceptable to decompress the data in
memory before the start of rendering - it is not necessary to render
directly from the VQ-compressed data.

<p>
<h3>IV. Writeup and analysis (10%)</h3>
<p>
Please submit your source code together with a writeup (as plain text,
HTML, or PDF) that contains a description of the design decisions you made,
options you implemented, and sample screen-shots.

<p>
<h3> Submitting </h3>
<p>
Please make your writeup and code accessible via the web, and send the URL
to <tt>funk@princeton.edu</tt> with "COS526" in the subject line.  Please
see the <a href="assignments.html#submitting">general notes on submitting
your assignments</a>, as well as the
<a href="assignments.html#late">late policy</a> and the
<a href="assignments.html#collaboration">collaboration policy</a>.

<!--#include virtual="footer.html" -->
