CS 523 - Fall 2003
Project 2: 3D NPR - Contours and Suggestive Contours
Due: Friday, Nov 14, noon (electronic handin)
|
Working from 3D geometry, approaches to non-photorealistic rendering
typically compute linear features directly on the model. The contour
has been a typical ingredient for many years
[Gooch 03]; the suggestive contour [DeCarlo et al
03] is a new addition.
In this project, you will implement algorithms to compute contours and
suggestive contours, and use OpenGL to render them.
You have the option of using OpenGL in C++ (with GLUT and GLUI), or
Java (using GL4Java). These are both set up in the cereal lab.
Requirements
- Mesh representation
- You will need a mesh representation that is simpler than
what you did for project 1. You will need to
support (at least):
- Each vertex storing a list of neighboring vertices
- Each vertex storing a normal vector averaged from
its neighboring faces
- Edges that store 2 vertices and 1 or 2 adjacent
polygons (1 adjacent polygon means the edge is on
a boundary)
As in project 1, the mesh should be placed so it's centered
at the origin, and fits into an x-y-z aligned bounding cube
of width 1. You should actually change the vertex locations,
and not just use OpenGL to do this--this way all of the
thresholds you apply below become independent of model
size.
To keep things simple, assume the meshes are "nice"
(i.e. all triangles, manifold geometry, etc...). If it
works on the example triangle meshes provided in OFF
format, it's ok.
-
Compute the location of the camera (given the current
viewing transformation) in object coordinates (i.e. the
same coordinate system as the vertex locations). You'll
need this later to compute the view vector v.
- Contours
- Determine the contours of the mesh defined as the edges
that separate front-facing and back-facing triangles.
- Compute (n DOT v) at every vertex, and determine
the contours as the zero crossings of this
quantity---as line segments that cross triangles.
(See section 4.1 of
[Hertzmann and Zorin 00] for details.)
- Draw the contours as line segments (add something to
the GUI that lets you select between the two extraction
methods), and use the Z-buffer to determine visibility.
You'll find that you'll want to be drawing boundary edges
as well (if the mesh has any).
- Suggestive contours
(For this part, all section and equation numbers are from
[DeCarlo et al
03].)
- Compute the zero crossings of the radial curvature
(Kr) using the same algorithm for contours as
zero-crossings. The radial curvature can be computed
from the gradient:
Kr * (w DOT w) = Dw (n DOT v) =
grad(n DOT v) DOT w
(See section 2.2.1 for why this is the case.)
Here, w is the projection of the view direction
onto the tangent plane.
- Discard those zero crossings based on equations (5)
and (7). Note that (7) subsumes (2).
Compute the required derivative of Kr using
the gradient of Kr:
Dw Kr = grad(Kr) DOT w
- Draw the suggestive contours, adding controls in the GUI
to enable (5) and (7) separately, and for setting these
two threshold values. Include the ability to turn
off suggestive contours altogether (and have your
code skip their extraction as well.)
Optional extensions
Here are just some ideas; feel free to add your own! Not all of these
extensions are independent--some require others to be done first. Ask
if you're not sure.
- Extract the contours using a non-exhaustive search (i.e.
probabilistic or hierarchical; see [Gooch 03]).
- Instead of computing line segments for the contours and
silhouettes, compute the closed loops---continuous chains of
line segments. Then, you can render the lines as a strip, which
produces much cleaner results.
- Produce cleaner loops using the hysteresis thresholding procedure
described in [DeCarlo et al 03; end of 3.1]
- Do better visibility computations as described in
[Hertzmann and Zorin 00] (note that the cusp function
is simply the radial curvature; and note that you'll need to
do something else to find the T-junctions), or using an ID reference
image as described in the WYSIWYG NPR paper [Kalnins 02; section 4.3].
- Join up the strokes for the contours and suggestive contours
where they cross (at the points of ending contour)
- Once you have loops, draw strokes made of triangle strips that
sit in the image plane (by computing the projection yourself,
you can get good control over the width of the line; perhaps
have them taper at the ends.
- Texture the strokes to give them an even better appearance.
Code
Start from code for project 1, located in:
~decarlo/523/proj1
on the cereal
machines, or from your solution to project 1.
A function to compute gradients of scalar functions on meshes
is provided in:
~decarlo/523/proj2
It is only provided
in C++, but is easy enough to convert to Java, and to your modified
mesh classes. (A minimally modified mesh.h file is also
provided with additional structure in the Vertex class.)
Models
Use the triangle meshes in OFF format located on the cereal machines in:
~decarlo/523/off
Work policy
You're allowed to talk about the assignment with other students in the
class, but you can't give away a key idea. Furthermore, all code you
write must be your own. No using or viewing code from other
sources/people/etc...
The exception is in replacing parts of the skeleton code that are
clearly not part of the requirements (i.e. a class that implements 3D
vectors, a user interface toolkit, etc...). When in doubt, ask.
Handin
Use the handin program on the cereal lab machines. See
the description here.
The name for this assignment is cs523-proj2.
Hand in the following:
- All the code and a Linux makefile to compile your assignments
(if you have a complex directory structure, feel free to hand in a
tar file)
- A file called README.TXT that contains (1) a description
of your assignment (i.e. what approaches you took, which
extra parts you did, what bugs you have), (2) instructions
on how to use it (if it's not obvious from the GUI)
Please double check that your assignment does indeed compile on the
Linux cereal lab machines before you hand in.
523 Home